1.流的定义和分类
流代表经过管道流通的数据。把不同的输入和输出源抽象表述为流。
按“数据流的方向”——输入流和输出流(以程序为参照物)
按“处理数据单位”——字节流和字符流(图片等多媒体等原始字节信息用自己流,文件等字符信息用字符流)
按“功能”——节点流和处理流
2.java.io包(所有流都继承以下抽象流类型)
|
字节流(8bit) |
字符流(16bit) |
输入流(向程序输入) |
InputStream |
Reader |
输出流 |
OutputStream |
Writer |
InputStream(Reader类似)
int read() //读取一个字节并以整数的形式返回,已到输入流结尾返回-1
int read(byte[] buffer) //读取一系列字节并存储到一个数组buffer,返回读取的字节数
int read(byte[] buffer, int offset, int length) //读取length个字节,并存储到buffer,从offset开始,…
long skip(long n) //跳过n个字节不读,返回实际跳过的字节数
void close()
OutputStream(Writer类似)
void write(int b) //向输出流,写入一个字节数据,该字节数据未参数b的低8位
void write(byte[] b) //将一个字节类型的数组中的数据写入输出流
void write(byte[] b, int off, int len) //将字节类型的数组从off开始的len个字节写入输出流
void flush() //将输出流中缓存的数据全部写出到目的地
3.字节流和处理流
节点流——可以从一个特定的数据源(节点)读取数据(如:文件、内存)
处理流——是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能
常用处理流:缓冲流、转换流、数据流、Print流、Object流
-------------------------------------
ByteArrayInputStream 把内存的一个缓冲区作为InputStream使用
StringBufferInputStream 把一个String对象作为InputStream
FileInputStream 把一个文件作为InputStream,实现对文件的读取操作
DataInputStream 从stream中读取基本类型数据
BufferedInputStream 使用缓冲区读取字节数据
PrintStream 产生格式化输出
4.如何判断读取文件是否到达末尾?
InputStream/Reader的read()返回-1
BufferedReader返回null
InputStream示例代码:
<!--WizRtf2Html Charset=0 --> int temp = -1;
while((temp = bufferedInputStream.read()) != -1) {
System.out.println((char)temp);
}
BufferedReader示例代码:
<!--WizRtf2Html Charset=0 --> String s = null;
while((s = bufferdeReader.readLine()) != null) {
System.out.println(s);
}
5.如何读文件,写文件?
// 读文件
---字节
int temp = -1;
while((temp = bufferedInputStream.read()) != -1) {
System.out.println((char)temp);
}
---字符
String temp = null;
while((temp = bufferdeReader.readLine()) != null) {
System.out.println(temp);
}
// 写文件
---字节
bufferedOutputStream.writr('A');
---字符
printWriter.print("格式化输出");
6.如何实现在文件的任意位置进行读写?
RandomAccessFile,特殊文件流,实现了DataInput/out接口因此可以读取写入文件。
RandomAccessFile通过一个文件指针来确定读取位置,默认文件开始处。指针可通过getFilePointer()获取,通过seek()设置。
构造方法RandomAccessFile(File file,String mode)/RandomAccessFile(String name, String mode)
r rw rws(要求更新要写入的文件内容及其数据) rwd(用于减少执行的IO操作数量,仅要求更新写入存储的文件内容)
7.使用Buffered缓冲流写文件,为什么内容没有写入?
在使用缓冲流写文件时,先将信息吸入缓冲区,如果不显示调用flush和close则无法将缓冲区信息输出到目标地点,因此文件为空。
OutputStream和Writer输出流中,都有flush和close。
flush用于刷新输出流并强制系写出所有缓冲的输出的字节
close方法用于关闭输出流并释放与此流有关的所有资源(close会默认执行flush功能)
8.读写文件时为什么中文字符经常产生乱码?
计算机只能识别二进制信息,都是以二进制形式存储。
字符集用于描述“字符”和“二进制”之间的映射关系,在编码和解码过程中都需要遵循相同的字符集才能正确显示。
1)由于编码和解码的字符集不同引起乱码
2)API使用不当,例如InputStream读取中文字符(2字节),InputStream会将中文字分拆成2个字节2次读取。
9.如何解决FileReader读取文件乱码问题?
开发者习惯选用FileReader读取文件,但同样出现乱码问题。
FileReader继承自InputStreamReader,其实内部实现过程中完成了字节流到字符流的转变,只不过转换时采用的字符集为系统平台默认的字符集。如果保持设置为UTF8,用中文操作系统(GBK)就会读取出错。
解决办法,放弃FileReader,获取Inputstream对象时显示指定合适的字符集
10.为什么DataInputStream和DateOutputStream读写文件会乱码?
该Stream可以以基本类型为单位对文件进行读写操作,例如写入一个int或读取一个boolean值。
使用DataOutputStream写入文件中的信息,除了包含信息之前外,还有“类型标识”等,只有使用DateInputStream才能正确读取原有信息,其他方式会产生乱码,这也是记事本打开文件时显示乱码的原因。