Java 输入输出流(二)
流就是内存与存储设备之间传输数据的通道
请看看图象形理解
流的分类
1.按流向分类
- 输入流: 将
存储设备
的内容读入到内存
中 - 输出流: 将
内存
中的内容写入到存储设备
中
2.按单位来区分
- 字节流: 以字节为单位,可以读写所有数据。
- 字符流: 以字符为单位,只能读写文本数据。
3.按功能来区分
- 节点流: 具有实际传输数据的读写功能。
- 过滤流: 在节点流的基础上的增强功能。
文件输入输出流,请看Java 输入输出流(一)
字节缓存流
- 缓冲流: BufferedInputStream/BufferedOutputStream
作用 - 提高IO效率,减少磁盘的访问次数
- 数据存储在缓冲区中,flush是将缓存区的内容写入到文件中,也可以直接close.
package com.sean.iotest;
import java.io.*;
public class Test <T> {
public static void main(String[] args) throws Exception {
InputStream inputStream = new FileInputStream("E://test/1.txt");
OutputStream outputStream = new FileOutputStream("E://test/2.txt");
BufferedInputStream bis = new BufferedInputStream(inputStream);
int data = 0;
while((data = bis.read())!=-1){
System.out.println((char)data);
}
bis.close();
}
}
上述代码,我们只关闭了缓冲流,为什么没有关闭字符输入流,其实在缓冲流关闭的时候,已经帮我们关闭了字符流,请看下面源码:
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* Once the stream has been closed, further read(), available(), reset(),
* or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
if (bufUpdater.compareAndSet(this, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
// Else retry in case a new buf was CASed in fill()
}
}
package com.sean.iotest;
import java.io.*;
public class Test <T> {
public static void main(String[] args) throws Exception {
InputStream inputStream = new FileInputStream("E://test/1.txt");
OutputStream outputStream = new FileOutputStream("E://test/2.txt");
BufferedInputStream bis = new BufferedInputStream(inputStream);
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
int data = 0;
while((data = bis.read())!=-1){
bos.write(data);
System.out.println((char)data);
}
bos.close();
outputStream.close();
bis.close();
}
}
缓冲流
- 对象流: ObjectOutputStream/ObjectInputStream
作用
1.增强了缓冲区功能
2.增强了读写8种基本数据类型和字符串功能
3.增强了读写对象的功能: a.readObject() 从流中读取一个对象 b.writeObject(Object obj) 向流中写入了一个对象。
使用流传输对象的过程称为序列化、反序列化。
序列化
package com.sean.iotest;
import java.io.*;
public class Test <T> {
public static void main(String[] args) throws Exception {
OutputStream outputStream = new FileOutputStream("E://test/2.obj");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
Student student = new Student("zhsnagsna ","12");
objectOutputStream.writeObject(student);
objectOutputStream.close();
}
}
反序列化
package com.sean.iotest;
import java.io.*;
public class Test <T> {
public static void main(String[] args) throws Exception {
InputStream inputStream = new FileInputStream("E://test/2.obj");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
Object o = objectInputStream.readObject();
if(o instanceof Student){
System.out.println(o);
}
objectInputStream.close();
}
}
序列化与反序列化时的注意事项
- 序列化的类必须要实现
Serializable
接口 - 序列化类中对象属性要求实现
Serializable
接口:比如学校类中的一个学生属性 - 序列化版本ID,保证序列化的类和反序列化的类是同一个类
- 使用
transient
来修饰不能序列化的属性 - 静态属性也是不能序列化的
- 序列化多个对象的时候可以借助对象
字符编码
在讨论字符流时,我们先来看看字符编码
- ISO-8859-1 收录了除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来 语对应的文字符号
- UTF-8 针对Unicode码表的可变长度字符编码
- GB2312 简体中文
- GBK 简体中文、扩充
- BIG5 繁体中文(台湾)
字符流
- 字符流的父类(抽象类):
1.Reader:字符输入流
2.Writer:字符输出流
文件字符流
- FileReader:
1.public int read(char[] c) //从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1 - FileWriter:
1.public void write(String str);//一次写多个字符,将b数组中所有字符,写入输出流。
package com.sean.iotest;
import java.io.*;
public class Test <T> {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("E://test/1.txt");
FileWriter fw = new FileWriter("E://test/2.txt");
int data = 0;
char [] c = new char[1024];
while((data = fr.read(c))!=-1){
fw.write(c);
System.out.println(c);
}
fw.close();
fr.close();
}
}
转换流
桥转换流: InputStreamReader/OutputStreamWriter
- 可将字节流转换为字符流。
- 可设置字符的编码方式。
package com.sean.iotest;
import java.io.*;
public class Test <T> {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("E:\\test\\1.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
FileOutputStream fileOutputStream = new FileOutputStream("E:\\test\\11.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"utf-8");
int data = 0;
while((data = inputStreamReader.read())!=-1){
outputStreamWriter.write(data);
System.out.println((char)data);
}
outputStreamWriter.close();
inputStreamReader.close();
}
}