Java的IO
java.io中定义了多个流类型,包括了类和抽象类;
关于IO流的理解
发挥形象思维,将流想象成管道,将数据源想象成水桶
IO流类型的分类
- 按照数据流向的不同可以分为输入流和输入流
- 按数据处理单位的不同可以分为字节流和字符流
- 按功能不同可以分为节点流和处理流
字节流与处理流
位于java.io内的所有流类型均继承自以下四种抽象类型
| 字节流 | 字符流 | |
|---|---|---|
| 输入流 | InputStream | Reader |
| 输出流 | OutputStream | Writer |
节点流与处理流
| 节点流 | 从一个特定的的数据源中读写数据(文件、内存) |
| 处理流 | "连接"在已经存在的流(节点流或者处理流)上,通过对数据的处理为程序提供更方便的读写功能 |
InputStream:所有以字节为单位的输入流的父类
继承自InputStream的流都是用于向程序输入数据的,且数据的单位为字节(8bit)
- InputStream
- FileInputStream
- PipedInputStream
- FilterInputStream
- LineNumberInputeStream
- DataInputStream
- BufferedInputStream
- PushbackInputStream
- ByteArrayInputStream
- SequenceInputStream
- StringBufferInputStream
- ObjectInputStream
以上加粗的为处理流
InputStream的基本方法
- int read() //读取一个字节并以证书的形式返回;当读取到末尾时返回-1
- int read(byte[] buffer) //读取一系列的字节并存入到字节数组buffer中,返回实际读取的字节数;当读取到末尾时返回-1
- int read(byte[] buffer, int offset, int length) //从第offset开始,读取length个字节到字节数组buffer中
- void close() //关闭输入流
- long skip(long n) //跳过n个字节不读,返回实际跳过的字节数
OutputStrem:所有以字节为单位的输出流的父类
继承自OutputStream的流都是用于程序中输出数据,且数据单位为(8bit)
- OutputStream
- FileOutputStream
- PipedOutputStream
- FilterOutputStream
- DataOutputStream
- BufferedOutputStream
- PrintStream
- ByteArrayOutputStream
- ObjectOutputStream
以上加粗的为处理流
OutputStream的基本方法
- void write(int b) //向输出流中写入一个字节数据,该字节数据为参数b的低8位
- void write(byte[] b) //向输出流中写入一个字节数组
- void write(byte[] b, int index, int length) //从指定位置index中开始写入length个字节到输出流中
- void close() //关闭输出流
- void flush() //讲缓存区中的数据全部写入
Reader:所有以字符单位的输出流的父类
所有继承自Reader的流都是用于向程序中输入数据,且数据单位为字符(16bit)
- Reader
- BufferedReader
- LineNumberReader
- CharArrayReader
- InputStreamReader
- FileReader
- FilerReader
- PushbackReader
- PipedReader
- StringReader
- BufferedReader
以上加粗的为处理流
Reader的基本方法
- int read() //读取一个字符并按照整数的形式返回;返回-1表示读到输入流末尾
- int read(char[] cbuf) //读取一系列字符,并存储到一个数组中,返回读取到的字符的个数;返回-1表示读到输入流末尾
- int read(char[] cbuf,int offset,int length) //从offset开始,读取length个字符,并存储到数组中,返回实际读取字符的个数;返回-1表示读到输入流末尾
- void close() //关闭输入流
- long skip(long n) //跳过n个字符不读,返回实际跳过的字节数
Writer:所有以字符为单位的输出流的父类
所有继承自Writer的流都是用于向程序中输出数据,且数据单位为字符(16byte)
- Writer
- BufferedWriter
- CharArrayWriter
- OutputStreamReader
- FileWriter
- FilterWriter
- PipedWriter
- StringWriter
以上加粗的为处理流
Writer的基本方法
- void write(int b) //向输出流中写入一个字符数据,该字节数据为参数b的低16位
- void write(char[] cbuf) //向输出流中写入一个字符数组
- void write(char[] cbuf, int offset, int length) //从字符组cbuf中的offset开始向输出流中写入length个字符
- void write(String string) //将字符串中的字符写入输出流中
- void write(string string, int offset, int length) //从字符串的offset位置开始,写入length个字符
- void close() //关闭输出流
- void flush() //讲缓存区中的数据全部写入
节点流类型
| 类型 | 字符流 | 字节流 |
|---|---|---|
| File | FileReader/FileWriter | FileInputStream/FileOutputStream |
| 数组 | CharArrayReader/CharArrayWriter | ByteArrayInputStream/ByteArrayOutputStream |
| 字符串 | StringReader/StringWriter | |
| 管道 | PipedReader/PipedWriter | PipedInputeStream/PipedOutputStream |
访问文件
FileInputStream/FileOutputStream
常用的构造方法
FileInputStream(String name)
FileInputStream(File file)
FileOutputStream(String name)
FileOutputStream(File file)
FileOutputStream(File file, boolean i)
//布尔值代表是否要覆盖就文件,不覆盖则在原来的基础上继续写入
实例代码
FileInputStream ip = new FileInputStream("/Users/g/Desktop/fips.rtf");
FileOutputStream op = new FileOutputStream("/Users/g/Desktop/fops.rtf");
int i = 0;
while ((i = ip.read()) != -1) {
System.out.print((char)i);
op.write(i);
}
op.flush();
op.close();
ip.close();
FileReader/FileWriter
示例代码
FileReader r = new FileReader("/Users/g/Desktop/fr.docx");
FileWriter w = new FileWriter("/Users/g/Desktop/fw.docx");
int i = 0;
while ((i = r.read()) != -1) {
System.out.print((char)i);
}
for(i=0; i <= 60000; i++) {
w.write(i);
}
r.close();
w.flush();
w.close();
处理流类型
| 处理类型 | 字符流 | 字节流 |
|---|---|---|
| Bufferring | BufferedReader/BufferWriter | BufferedInputStream/BufferedOutputStream |
| Filtering | FilterReader/FilterWriter | FilterInputStream/FilterOutputStream |
| Converting between bytes and character | InputStreamReader/OutputStreamWriter | |
| Object Serialization | ObjectInputStream/ObjectOutputStream | |
| Data conversion | DataInputStream/DataOutputStream | |
| Counting | LineNumberReader | LineNumberInputStream |
| Peeking ahead | PushbackReader | PushbackInputStream |
| Printing | PrintWriter | PrintStream |
缓冲流(BufferedReader、BufferedWriter、BufferedInputStream、bufferedOutputStream)
在内存中提供缓存区域,显著的减少硬盘的读写次数,减少对于多次读写对于硬盘的损害
常用的构造方法
BufferedReader(Reader in)
BufferedReader(Reader in, int size)
BufferedWriter(Writer out)
BufferedWriter(Writer out, int size)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size)
bufferedOutputStream(OutputStream out)
bufferedOutputStream(OutputStream out, int size)
其中size用于表示缓存区域的大小
常用方法
BufferedReader提供了readLine()方法用于读取一行字符串
BufferedWriter提供了newLine()方法用于写入一个行分隔符
示例代码
BufferedReader br = new BufferedReader(new FileReader("/Users/g/Desktop/JavaIOTest/bf.txt"));
int j = 0;
while ((j = (br.read())) != -1) {
System.out.print((char)j);
}
System.out.println();
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/g/Desktop/JavaIOTest/bw.txt"));
for (int i = 'a'; i <= 'z'; i++) {
bw.write(i);
bw.newLine();
}
bw.flush();
br = new BufferedReader(new FileReader("/Users/g/Desktop/JavaIOTest/bw.txt"));
String k = null;
while ((k = (br.readLine())) != null) {
System.out.println(k);
}
bw.close();
br.close();
注意:使用wps创建的文件读取的内容中会有多余的内容,暂时还没搞清楚是怎么回事
BufferedWriter中flush的几种情况
- 缓冲区满了的时候会自动flush
- 手动调用flush
- 调用close()时如果缓存区还有内容将会调用flush方法
转换流(InputStreamReader、OutputStreamWriter)
提供从字节流转换为字符流的功能,并且还可以在构造时指定编码
常用的构造方法
InputStreamReader(InputStream in, String encode) OutputStreamWriter(OutputStream out, String encode)
示例代码
FileInputStream ip = new FileInputStream("/Users/g/Desktop/JavaIOTest/g.txt");
FileOutputStream op = new FileOutputStream("/Users/g/Desktop/JavaIOTest/g.txt",true);
InputStreamReader ir = new InputStreamReader(ip,"UTF-8");
OutputStreamWriter ow = new OutputStreamWriter(op,"UTF-8");
ow.write("什么?!!让我试试行不行ABCD");
ow.flush();
ow.close();
BufferedReader br = new BufferedReader(ir);
String k = null;
while ((k = (br.readLine())) != null) {
System.out.println(k);
}
br.close();
系统的标准输入输出System.in、System.out
in、out分别是InputStream和OutputStream
因此他们作为参数可以通过键盘输入的方式对流进行读写
示例代码
InputStreamReader ir = new InputStreamReader(System.in,"UTF-8");
BufferedReader br = new BufferedReader(ir);
System.setOut(new PrintStream(new FileOutputStream("/Users/g/Desktop/JavaIOTest/g.txt",true)));
System.out.println(br.readLine());
ByteArrayInputStream
对字节数组进行读取
构造方法
ByteArrayInputStream(byte[] buf)
ByteArrayOutputStream
对指定的字节数组进行输出
构造方法
ByteArrayInputStream()//默认32位字节数组
ByteArrayInputStream(int size)//指定size位字节数组
数据流(DataInputStream、DataOutputStream)
提供与机器无关的Java的原始数据类型的方法
常用的构造方法
DataInputStream(InputStream in)
DataOutputStream(OutputStream out)
示例代码
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream ds = new DataOutputStream(b);
ds.writeChars("摩西摩西");
ds.writeInt(123);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b.toByteArray()));
System.out.println(dis.readChar());
System.out.println(dis.readChar());
System.out.println(dis.readChar());
System.out.println(dis.readChar());
System.out.println(dis.readInt());
ds.close();
dis.close();
注意:需要按照先进先出的原则进行读取,不然会出现错误
Print流(PrintWriter、PrintStream)
都属于输出流,他们有自动flush的功能,用于多种数据的输出,并且不会抛出异常
常用的构造方法
PrintWriter(Writer out)
PrintWriter(Writer out, boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)
PrintStream(OutputStream out)
PrintStream(OutputStream out, boolean autoFlush)
示例代码
InputStreamReader ir = new InputStreamReader(System.in,"UTF-8");
BufferedReader br = new BufferedReader(ir);
System.setOut(new PrintStream(new FileOutputStream("/Users/g/Desktop/JavaIOTest/g.txt",true)));
System.out.println(br.readLine());
Object流(ObjectInputStream、ObjectOutputStream)
直接将Object写入或者读出
serializable接口
Java提供序列化的接口,如果需要序列化只需要实现该接口,java编译器就会自动实现序列化
externalizable接口
同样也是需要序列化时使用到的接口,与serializable接口不同的事,需要自行实现序列化
修饰词transient
在实现了serializable接口的类中,使用transient修饰词可以决定那些变量不被序列化,也就是说将变量的寿命控制在内存中。需要注意的是该修饰词对于实现externalizable的类是无效的。
示例代码
public static void ObjectIOTest() throws IOException, ClassNotFoundException {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("/Users/g/Desktop/JavaIOTest/Object.txt"));
os.writeObject(new Test());
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/g/Desktop/JavaIOTest/Object.txt"));
Test t = (Test)ois.readObject();
System.out.println(t.a);
System.out.println(t.b);
System.out.println(t.c);
System.out.println(t.d);
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectIOTest();
}
public static class Test implements Serializable {
int a = 10;
boolean b = false;
double c = 3.5;
String d = "小明";
}