Java流类图结构
IO流的分类
根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流
按照流的角色划分为:节点流和处理流
字符流的由来:因为文件编码的不同,而有了对字符进行高效的字符流对象
原理:其实就是基于字节流去读取字节时,去查了指定的码表。字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。
字节流和字符流的区别:
- 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
- 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
字节流和字符流的原理是相同的,只不过处理的单位不同而已。后缀是Stream是字节流,而后缀是Reader,Writer是字符流。设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。
结论:如果只是处理纯文本数据,就要优先考虑使用字符流,除此之外都要使用字节流。
输入流和输出流区别
- 输入流: 只能从中读取数据,而不能向其写入数据。
- 输出流:只能向其写入数据,而不能向其读取数据。
节点流和处理流区别
- 节点流也被称为低级流,以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流.
- 处理流也被称为高级流,用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能。
处理流的优点;
- 性能的提高:主要以增加缓冲的方式来提供输入和输出的效率。
- 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入和输出大批量的内容,允许JAVA应用程序采用相同的代码,透明的方式来访问不同的输入和输出设备的数据流,
转换流
1、 InputStreamReader:字节到字符的桥梁
2、 OutputStreamWriter:字符到字节的桥梁
特点
1、 是字节流和字符流之间的桥梁
2、 该流对象中可以对取到的字节数据进行指定编码表的编码转换。
什么时候使用?
1、 当字节和字符之间有转换动作时
2、 流操作的数据需要进行编码表的指定时
使用Demo:
new BufferedReader(new InputStreamReader(new FileInputStream("D:\\test.txt"), "UTF-8"));
流的操作小结:
读取数据源:InputStream、Reader
写入数据源:OutputStream、Writer
纯文本操作 Reader,Writer
非文本操作:InputStream,OutputStream
数据源设备:硬盘(File),内存(数组),键盘(System.in)/(System.out)
对数据源做附加处理(处理流),Buffered,Pipe,Array等装饰流
尽可能的多使用处理流,这会使我们的代码更加灵活,复用性更好。
常用的处理流
缓冲流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
转换流:InputStreamReader 、OutputStreamReader实现字节流和字符流之间的转换。
数据流: DataInputStream 、DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。
Demo
static void FileReaderTest() throws IOException {
FileReader reader = null;
try {
reader = new FileReader("D:\\test.txt");
char[] b = new char[1024];
while (reader.read(b) > 0) {
System.out.println(new String(b));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
reader.close();
}
}
static void FileReaderWriteTest() throws IOException {
Reader reader = null;
FileWriter writer = null;
try {
// 直接使用FileReader,遇到一些特殊字符(如中文)可能会出现乱码,
// reader = new FileReader("D:\\test.txt");
reader = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\test.txt"), "UTF-8"));
writer = new FileWriter("D:\\test3.txt");
char[] b = new char[1024];
int readLength = 0;
while ((readLength = reader.read(b)) > 0) {
writer.write(b, 0, readLength);
System.out.println(new String(b));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static void FileStreamWriteTest() throws IOException {
FileInputStream reader = null;
FileOutputStream writer = null;
try {
reader = new FileInputStream("D:\\test.txt");
writer = new FileOutputStream("D:\\testStream.txt");
//字节类型使用的是 byte
byte[] b = new byte[1024];
int readLength = 0;
while ((readLength = reader.read(b)) > 0) {
writer.write(b, 0, readLength);
System.out.println(new String(b));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static void FileStreamWriteWithBufferTest() throws IOException {
FileInputStream reader = null;
FileOutputStream writer = null;
BufferedInputStream bReader = null;
BufferedOutputStream bWriter = null;
try {
reader = new FileInputStream("D:\\test.txt");
writer = new FileOutputStream("D:\\testStreamBuffer.txt");
bReader = new BufferedInputStream(reader);
bWriter = new BufferedOutputStream(writer);
String strLine=null;
//返回这个输入流中可以被读的剩下的bytes字节的估计值;
int nSize = bReader.available();
//这有一个弊端,就是文件过大,大小超出jvm的内容空间时,会内存溢出。
byte[] b = new byte[nSize];
bReader.read(b);
bWriter.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
//处理流会关闭底层的流
try {
bReader.close();
bWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static void FileStreamWriteWithBufferReader() throws IOException {
BufferedReader reader=null;
BufferedWriter writer=null;
try {
reader = new BufferedReader(new FileReader("D:\\test.txt"));
writer= new BufferedWriter(new FileWriter("D:\\testStreamBufferReader.txt"));
String strLine=null;
while ((strLine=reader.readLine())!=null){
writer.write(strLine);
writer.newLine();
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//处理流会关闭底层的流
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}