系列文章目录
Java自学日记之IO流(一):字节流和字符流
Java自学日记之IO流(二):转换流(InputStreamReader、OutputStreamWriter)
Java自学日记之IO流(三):缓冲流(BufferedInputStream、BufferedOutputStream)
Java自学日记之IO流(四):字节数组流(ByteArrayInputStream、ByteArrayOutputStream)
前言
我们之前讨论过
如何读取文件里的字节
如何把字符转换成字节
如何不依赖文件读取字节数组的字节
如何更高效地读取字节(缓冲流)
不难发现,我们读取数据基本上读的都是字符或者字节,但是日常读取文件时除了字符和字节外,还有很多基本的数据类型(int,double,long…),显然读取它们的时候需要先对这种数据类型进行转换,转换成我们需要的字节或字节数组,其实这操作并不麻烦,好多流中有这种转换函数,比如FileInputStream,但是我们还缺少一种系统处理这些文件的流
一、数据流介绍
- 数据流属于一种处理流,所以他也是要套在一个原始流之上的
- 数据流提供了可以存取与机器无关的Java原始类数据(如:int,double等)的方法
需要注意的是,数据流本身是FilterInputStream/FilterOutputStream的子类,它套接的底层数据流也是要求是字节流的子类,而它的各种read/write方法也是要调用套接流的read/write方法的,所以最好不要用它读取多字符型数据(汉字),大概率会失精乱码。
二、构造方法
1.DataInputStream构造
内部实现了一个字节数组和一个字符数组的存储,但是仅用于readUTF方法
/**
* working arrays initialized on demand by readUTF
*/
private byte bytearr[] = new byte[80];
private char chararr[] = new char[80];
构造方法就一种
/**
* Creates a DataInputStream that uses the specified
* underlying InputStream.
*
* @param in the specified input stream
*/
public DataInputStream(InputStream in) {
super(in);
}
可以看出这个流很省心,构造只需要套接一个底层输入流,存储在FilterInputStream里
2.DataOutputStream构造
提供了一个字节数组,也是仅用于writeUTF方法
/**
* bytearr is initialized on demand by writeUTF
*/
private byte[] bytearr = null;
提供了一个int型数据用来标记目前写入了多少字节
/**
* The number of bytes written to the data output stream so far.
* If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
*/
protected int written;
它本身的构造方法也是仅有一种
/**
* Creates a new data output stream to write data to the specified
* underlying output stream. The counter <code>written</code> is
* set to zero.
*
* @param out the underlying output stream, to be saved for later
* use.
* @see java.io.FilterOutputStream#out
*/
public DataOutputStream(OutputStream out) {
super(out);
}
套一个底层输出流就行
三、各种read()方法
把各种底层输入流的数据读到程序里面
内容太多了,直接上图吧
雨露均沾
但其实看着多,内部实现都是大同小异
里面的所有read函数基本上都是先调用的in.read(),读出来几个字节然后进行简单处理
需要注意的是我们读取数据时,如果之前用DataOutputStream写入数据了,那么我们读取数据时的数据类型顺序要和DataOutputStream写入时的数据类型顺序对应上,要不然可能会造成DataInputStream多读了几个字节,把写入的基本数据类型强拆开来
eg
//写入数据流
fileOutputStream=new FileOutputStream("abc.txt");
dataOutputStream=new DataOutputStream(fileOutputStream);
//调用的是FileOutputStream.write()方法,会将数据转成字节码,可能会失精
//所以用dataOutputStream写入文件时,最好只写入byte型数据,其他类型建议调用字符流方法
dataOutputStream.writeBoolean(true);
dataOutputStream.writeInt(99);
dataOutputStream.writeShort(111);
dataOutputStream.writeDouble(3.14);
//读取数据流
fileInputStream = new FileInputStream("abc.txt");
dataInputStream = new DataInputStream(fileInputStream);
//读取数据时,数据类型的顺序要与写入时一样。。。
System.out.println(dataInputStream.readBoolean());
System.out.println(dataInputStream.readInt());
System.out.println(dataInputStream.readShort());
System.out.println(dataInputStream.readDouble());
四、各种write()方法
把各种数据写入底层输出流
write也是一大堆
主要就是先把数据转换成字节或字节数组,再调用out.write()方法写入
总结
数据流实在是没啥讲的,感觉它本身就是提供了数据转字节的方法,没有什么特别有难度的方法,我还特意去百度上查了一下别人写的,看有没有遗漏什么重要的点,发现都没写多少,,就这样吧
I/O流就先写到这了,子类太多,挨个写一篇博客太费时间了,战线拉的太长了,该学新的知识点了