java数据流_java数据流例子

本文介绍了Java中的I/O流,包括输入流、输出流、节点流和处理流的分类,以及InputStream、OutputStream、FileInputStream、FileOutputStream等基础流的使用方法。通过实例展示了如何进行文件读写操作,并探讨了BufferedInputStream、BufferedOutputStream、DataInputStream和DataOutputStream等高级流的用法,最后提及了Reader和Writer字符流的应用。
摘要由CSDN通过智能技术生成

I/O流可谓是博大精深呀,今天总结一下今天所学到的东西吧:

首先理解一下I/O流的概念吧,Java的I/O流是实现输入、输出的基础,它可以方便实现数据的输入、输出操作,Java中把不同的输入、输出流抽象地表述为“流”,通过流的方式允许Java程序使用相同的方式来访问不同的输入、输出流。InputStream和OutputStream是两个处理字节流的基础的类(且为抽象类),而用于处理字符流的两个基础的类是Reader和Writer,所有其他的流类都是以这4个类为基础的。

按不同的方式可以把流分为不同的类:

1.按照流的方向分为输入流和输出流

输入流:只能从中读取数据,而不能向其中写入数据(如InputStream、FileInputStream);

输出流:只能向其中写入数据,而不能向其中读取数据(如OutputStream、FileOutputStream等);

2.按照流的角色分为节点流和处理流

节点流:可以向一个特定的IO设备读/写数据的流,也称作基础流、低级流(FileInputStream、FileOutputStream)

处理流:实现对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读/写功能的流,也称作高级流、包装流(如BufferedInputStream/BufferedOutputStream缓冲流DataInputStream/DataOutputStream数据流);它同时也是IO的精华—>基础流中构造中参数是介质,而处理流中构造中参数是流。

下面看几个实例吧:

第一部分:先看看基础流吧!

实例一:InputStream和OutputStream

这两个流是抽象类,提供了输入/输出处理的基本接口,并且实现了其中的一些方法,他们读/写流的方式是以字节为单位进行的。

InputStream用于从源按照字节读取数据,它定义了一下一些方法:

int read():从输入流中读取数据的下一个字节,并将它返回。如果遇到源的末尾,则返回-1,可以利用这一点判断是否已经到了流的末尾;

int read(byte[] buffer):将数据读入一个字节数组中,同时返回读取的字节数。同样如果遇到源的末尾,则返回-1;

int read(byte[] buffer,int offset,int length):将数据读入一个字节数组,放到数组的offset指定的位置开始,并用length来指定读取的最大字节数同样如果遇到源的末尾,则返回-1;

void close():用于关闭该流,在使用完流以后,一定要记得使用此方法关闭,否则数据可能不会写入文件;

void close():用于冲刷数据流,将数据写入文件,close方法中会先执行此方法。

*注意一点:缓冲区是采用数据覆盖的形式进行传递数据的。

下面看一个代码:package day11.io;

import java.io.*;

public class TestTestInputStream {

public static void main(String[] args) throws Exception {

int size;

InputStream is = new FileInputStream("E:\\test.txt");//input流需要先创建文件

System.out.println("可读取 的字节:"+(size=is.available()));

byte[] t = new byte[200];

for(int i=0;i

t[i] = ((byte)is.read());

System.out.println(t[i]);

}

System.out.println();

OutputStream os = new FileOutputStream("E:\\test.txt");

byte[] c = new byte[200];

for(int j = 0;j<200;j++){

c[j] =(byte)(j);

os.write(c[j]);

}

os.close();

is.close();

}

}

上述代码中用了try、catch直接处理了IO异常,调用read方法时,文件必须存在,调用write方法时会自动创建一个文件。

实例二:FileInputStream和FileOutputStream

他们分别是InputStream和OutputStream的子类,在生成FileInputStream和FileOutputStream类的对象时,如果指定的文件找不到,都会产生FileNotFoundException异常,因此必须捕获或抛出异常。

下面看一个代码:package day11.io;

import java.io.*;

public class TestIo {

public static void main(String[] args) {

InputStream is = null;

OutputStream os = null;

try {

//使用read方法时,文件必须存在

//write方法会自动创建一个文件(如果没有这个文件)

os = new FileOutputStream("D:\\2.txt");

os.write(98);

byte[] c = new byte[]{1,2,3};

os.write(c);

System.out.println();

is = new FileInputStream("D:\\2.txt");//会报错java.io.FileNotFoundException:

int i = is.read();

System.out.println(i);

System.out.println(c.length);

} catch (IOException e) {

e.printStackTrace();

}finally{

try {

is.close();

os.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

实例三:FileInputStream和FileOutputStream进行文件内容复制,利用write是可以创建文件的特点,复制出另一个内容一模一样的文件,为了提高复制效率,引进了数组,如果不写flush() 和close(),那么复制出的文件会变小,如果write中参数不加后面两个,那么复制出的文件会变大。下面看一下例子

package blog;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

public class TestCopy {

public static void main(String[] args) throws Exception {

File file1 = new File("E:\\test.txt");

File file2 = new File("E:\\tt.txt");

FileInputStream fis = new FileInputStream(file1);

FileOutputStream fos = new FileOutputStream(file2);

int i;

byte[] buff = new byte[8*1024];

while((i=fis.read(buff))!=-1){

fos.write(buff,0,i);

}

System.out.println("succees!");

System.out.println("file1的大小为:"+file1.getUsableSpace()+" ");

System.out.println("file2的大小为:"+file2.getUsableSpace()+" ");

// file1.delete();完成了剪切功能

fis.close();

fos.close();

}

}

输出结果如下所示:

succees!

file1的大小为:73930264576

file2的大小为:73930264576

程序结合了InputStream和OutputStream的用法,通过一个FileInputStream从一个文件中读出文件内容,然后将它作为FileOutputStream的输出,写入另一个文本文件,这样就完成了复制。

第二部分:接下来看看高级数据流^_^

高级流是对基础流进行了封装,并有许多功能的扩展,下面介绍几个常用的高级数据流:

1.BufferedInputStream和BufferedOutputStream

实现了带缓冲的过滤流,在读写的同事对数据进行缓存,这样可以避免每次读写或发送数据时都要进行实际的物理读写操作,因此在输入输出时经常用到这两个类。在用BufferOutputStream输出时,数据先输入缓冲区,缓冲区大小默认为8K,当缓冲区满时再写入连接的输出流,可以调用flush()方法来清空缓冲区。

看一个代码理解一下:

实例四:

Buffered...有很多方法,在这里就不一一列举了,读者可以查相应的api。

下面的方法复制了一个相同的文件:package day11.io;

import java.io.*;

public class TestFileCopy {

public static void main(String[] args) throws IOException {

FileInputStream fis = new FileInputStream("D:\\1.txt");

FileOutputStream fos = new FileOutputStream("D:\\2.txt");

BufferedInputStream bis = new BufferedInputStream(fis);

BufferedOutputStream bos = new BufferedOutputStream(fos);

int i = 0;

//默认读的是8K,要是缓冲取满了会自动写入文件里的

while((i=bis.read())!=-1){

bos.write(i);

}

// bos.flush();//冲刷缓冲区,强制将缓冲区中的内容写入文件

// bos.close();//关闭缓冲区在close之前会先flush的

}

}

下面说一下System.setOut();方法,它可以控制输出方式,即在控制台输出还是在文件中输出。package day11.io;

import java.io.*;

public class TestSISO {

public static void main(String[] args) throws IOException {

// 从控制台读一行

// Scanner是5.0之后提供的类。

InputStream is = System.in;

InputStreamReader isr = new InputStreamReader(is);

BufferedReader br = new BufferedReader(isr);

String s = br.readLine();

//需要在控制台路数数据然后直接在控制带显示;

System.out.println(s);

//PrintStream 中的println方法经常和BufferedReader的readLine()配合使用。

PrintStream ps = new PrintStream(new File("D:\\a.txt"));

System.out.println("控制台输出!");

System.setOut(ps);

System.out.println("文件中输出!");

ps.print("I'm coming!");

ps.print(s);

}

}

控制台输出如下:wo

wo

控制台输出!

文件中内容如下:文件中输出!

I'm coming!

2.DataInputStream和DataOutputStream

它们同样分别继承自FilterInputStream和FilterOutputStream,可以用与计算机无关的格式读写Java的基本数据类型以及String对象,DataInputStream中对应的以read开头,如readByte(),readDouble等等,write也同样。

在上一个代码的基础上增加了此数据流的功能:

实例五:package day11.io;

import java.io.*;

public class TestDataFlow {

public static void main(String[] args) throws IOException {

//Data数据流中包含了8种基本数据流的重载,可输入8种,另外还可查看api还有别的

File file = new File("D:\\a.txt");

FileOutputStream fos = new FileOutputStream(file);

DataOutputStream dos = new DataOutputStream(fos);

BufferedOutputStream bos = new BufferedOutputStream(dos);

dos.writeChar('M');

dos.writeDouble(1.34154);

dos.writeUTF("家");

FileInputStream fis = new FileInputStream(file);

DataInputStream dis = new DataInputStream(fis);

BufferedInputStream bis = new BufferedInputStream(dis);

char a = dis.readChar();

double d = dis.readDouble();

String s = dis.readUTF();

System.out.println(a+" "+s+" "+d);

//只需要关闭外层的就可以啦,它会自动关闭内层的流

dis.close();

dos.close();

}

}

输出如下:

M 家 1.34154

Data...数据流则比较人性化,多了很多方法,提供更多数据类型,writeUTF也提供了汉字的输入~

3.ObjectInputStream和ObjectOutputStream

万物皆OBJ,同样数据流也有Object类型的,见闻知其意,即数据流中传递的是对象的类型,下面看个小例子:

实例六:

首先实体类如下:package day11.io;

import java.io.Serializable;

public class Pet implements Serializable{

private String name;

private int age;

public Pet() {

super();

// TODO Auto-generated constructor stub

}

public Pet(String name, int age) {

super();

this.name = name;

this.age = age;

}

@Override

public String toString() {

return "Pet [name=" + name + ", age=" + age + "]";

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + age;

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Pet other = (Pet) obj;

if (age != other.age)

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

实体类代码中均未自动生成的方法,在写这个的时候明确了一点概念:Collection和Serializable接口均无字段和方法,Compatable只有一个方法即compareTo(),然后写一下为其测试类,将对象的数据存入D:\\Pet.content的文件中,然后从中读取Pet类的数据:package day11.io;

import java.io.*;

public class TestPetOOSIOS {

public static void main(String[] args) throws Exception {

File file = new File("D:\\Student.content");

FileOutputStream fos = new FileOutputStream(file);

ObjectOutputStream oos = new ObjectOutputStream(fos);

Pet p1 = new Pet("七仔",5);

oos.writeObject(p1);

FileInputStream fis = new FileInputStream(file);

ObjectInputStream ois = new ObjectInputStream(fis);

Pet p2 = (Pet) ois.readObject();

System.out.println("MY Dog'name is "+p2.getName()+"! \r\nAnd his age is "+p2.getAge()+" years old!");

oos.close();

ois.close();

}

测试结果如下:

MY Dog'name is 七仔!

And his age is 5 years old!

同样还可定义另一个类让其成为本实体类的属性,然后同样也就可以传递这个类的数据流了

4.Reader和Writer

它处理的是字符类型的数据流,它也分高级流和低级流;

Reader与InputStream相同用于从流中读取数据,它的方法如下:

int read():用于从流中读出一个字符,并将其返回。

int read():将从流中读出的字符放到字符数组buffer中,返回读出的字符数。

Int read(char[] buffer,int offset,int length):将读出的字符放到字符数组的指定offset开始的空间,每次最多读出length个字符。

Void close():关闭Reader流,在使用完Reader流后,一定记得将其关闭。

Boolean ready():判断流是否已经准备好被读取。

其他等方法可查看api文档。

Writer与OutputStream类似,用于向流中写入数据,它的方法如下:

void write(int c)

void write(char[] buffer)

void write(char[] buffer,int offset,int length)

void write(String string)

void write(String string,int offset,int length)

均为write方法的重载,意义同以上的read方法差不多

void close(),void flush()方法与以前的相同。

实例七:package day11.io;

import java.io.*;

public class TestReader {

public static void main(String[] args) throws IOException {

File file = new File("D:\\a.txt");

FileReader fr = new FileReader(file);//同一下两句的效果相同,但前提是保证是gbk编码

// FileInputStream fis = new FileInputStream(file);

// InputStreamReader isr = new InputStreamReader(fis,"gbk");

char c = (char)fr.read();

System.out.println(c);

//注意输入编码格式要一致

FileOutputStream fos = new FileOutputStream(file);

OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");

osw.write("中国");

for(int i=0;i<65535;i++){

osw.write(i);

} fr.close();

osw.close();

}

}

下面一个是用了Readre和Writer的方法package day11.io;

import java.io.*;

public class TestBuffered {

public static void main(String[] args) throws IOException {

File file = new File("D:\\a.txt");//得先有这个文件

FileInputStream fis = new FileInputStream(file);

InputStreamReader isr = new InputStreamReader(fis);

BufferedReader br = new BufferedReader(isr);

String str = null;

while((str = br.readLine())!=null){

System.out.println(str);

}

FileOutputStream fos = new FileOutputStream(file);

OutputStreamWriter osw = new OutputStreamWriter(fos);

BufferedWriter bos = new BufferedWriter(osw);

bos.write("一二三四五");

bos.newLine();// 新起一行。

bos.write("六七八九十");

bos.flush();// 注意冲刷

bos.close();

br.close();

}

}

在a.txt中输出了几乎所有的编码。在这个学习中有明确了一点编码小问题:对于汉字来说,gbk/gb2312占两个字节,utf-8占三个字节。

I/O果然是个不同凡响的东西,内容好多,以后再慢慢聊吧,今天就到这样了~晚安!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值