I:负责把磁盘和网络中的数据读到程序内存中去。
O:负责把程序内存中的数据写到网络或者磁盘中。
按照流的内容,IO流分为字节流和字符流。
字节流:最小单位是字节。适合操作所有类型的文件。比如音频、视频、图片文本等的复制,转移。
字符流:只适合操作纯文本文件。比如读写txt,java文件等。
结合IO和字节流字符流,可分为下面4种。
- 字节输入流 InputStream
- 字节输出流 OutputStream
- 字符输入流 Reader
- 字符输出流 Writer
字节流
抽象类 | 对应的实现类 |
---|---|
字节输入流 InputStream |
文件字节输入流 FileInputStream |
字节输出流 OutputStream |
文件字节输出流 FileOutputStream |
文件字节输入流 FileInputStream
作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去。
使用构造器创建文件字节输入流
创建字节输入流管道与源文件接通。
public FileInputStream(File file)
public FileInputStream(String pathName) //一般用这个
InputStream is = new FileInputStream("good.txt");
字节输入流管道对象的read()方法
方法 | 说明 |
---|---|
public int read() | 每次读取一个字节返回,如果发现没有数据可读会返回-1 |
public int read(byte[] buffer) | 每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1 |
// 1.创建管道与文件连接
InputStream is = new FileInputStream("111.txt");
// 2.定义一个字节数组用于每次读取字节
byte[] buffer = new byte[1024];
// 3.定义一个变量记住每次读多少字节
int len;
// 4.循环读取并转成字符
while( (len = is.read(buffer)) != -1) {String str = new String(buffer, 0 ,len);System.out.print(str);
}is.close();
文件字节输出流 FileOutputStream
作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。
使用构造器创建文件字节输出流
构造器 | 说明 |
---|---|
public FileOutputStream(File file) | 创建字节输出流管道与源文件对象接通 |
public FileOutputStream(String filepath) | 创建字节输出流管道与源文件路径接通 |
public FileOutputStream (File *file, boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
public FileOutputStream(String filepath, boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
字节输出流管道对象的write()方法
方法名称 | 说明 |
---|---|
public void write(int a) | 写一个字节出去 |
public void write(byte[] buffer) | 写一个字节数组出去 |
public void write(byte[] buffer, int pos , int len) | 写一个字节数组的一部分出去 |
public void close() throws IOExcention | 关闭流 |
byte[] bytes = "我爱你中国666".getBytes();
os.write(bytes); //我爱你中国666
os.write(bytes,0,3); //我
os.close();
换行符一般使用
"\r\n"
。
使用完流之后,需要马上关闭,因为这个管道占用的是硬件总线资源。
字节流的应用——文件复制
任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,复制前后的文件格式一致就没问题!
复制过去必须要带文件名!
InputStream fis = new FileInputStream(srcPath);
OutputStream fos = new FileOutputStream(destPath);byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){fos.write(buffer,0,len);
}fis.close();
fos.close();
管道资源的释放方案
如何确保流一定能够被释放?如果发生意外,导致代码没有执行close()
方法,怎么办?
方案一:使用finally代码区(不推荐)
finally代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止。
//1.创建一个文件字节输入流管道与源文件连通
InputStream fis = null;
Outputstream fos = null;
try {fis = new FileInputStream(srcPath);fos = new FileOutputStream(destPath);//2.读取一个字节数组,写入一个字节数组byte[] buffer = new byte[1024];int len;while((len = fis.read(buffer))!= -1) {fos.write(buffer, 0, len);}System.out.println("复制成功!");
} catch (Exception e) {e.printStackTrace();
} finally {//3.释放资源try {if(fos != null) fos.close():} catch (Exception e) {e.printStackTrace;}try {if(fis != null) fis.close;} catch (Exception e) {e.printStackTrace;}
}
方案二:使用try-with-resource(推荐)
JDK7开始提供的更简单的资源释放方案。
try (// 1.在这里定义资源,用完后会自动调用其close方法关闭!InputStream fis = new FileInputStream(scPath);OutputStream fos = new FileOutputStream(destPath);){// 2.读取一个字节数组,写入一个字节数组byte[] buffer = new byte[1024];int len;while((len = fis.read(buffer))!= -1) {fos.write(buffer, 0, len);} system.out.println("复制成功!");
} catch (Exception e) {e.printStackTrace);
}
- 资源不一定是管道资源,资源一般指的是最终实现了
AutoCloseable
接口的资源。- 资源使用完毕后,会自动调用其
close()
方法,完成对资源的释放。
字符流
抽象类 | 对应的实现类 |
---|---|
字符输入流 Reader |
文件字符输入流 FileReader |
字符输出流 Writer |
文件字符输出流 FileWriter |
文件字符输入流 FileReader
作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。
使用构造器创建文件字符输入流
创建字符输入流管道与源文件接通。
public FileReader(File file)
public FileReader(String pathName) //一般用这个
字符输入流管道对象的read()方法
方法 | 说明 |
---|---|
public int read() | 每次读取一个字符返回,如果发现没有数据可读会返回-1 |
public int read(byte[] buffer) | 每次用一个字符数组去读取数据,返回字符数组读取了多少个字节,如果发现没有数据可读会返回-1 |
文件字符输入流每次读取多个字符,性能较好,而且读取中文是按照字符读取,不会出现乱码!这是一种读取中文很好的方案。
- 创建文件字符输入流管道。
- 定义一个字符数组,每次读多个字符。
- 定义一个变量记录读取长度。
- 循环读取。
文件字符输出流 FileWriter
使用构造器创建文件字符输出流
构造器 | 说明 |
---|---|
public FileWriter(File file) | 创建字符输出流管道与源文件对象接通 |
public Filewriter(String filepath) | 创建字符输出流管道与源文件路径接通 |
public FileWriter (File file, boolean append) | 创建字符输出流管道与源文件对象接通,可追加数据 |
public FileWriter(String filepath, boolean append) | 创建字符输出流管道与源文件路径接通,可追加数据 |
字符输出流管道对象的write()方法
方法名称 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(String str) | 写一个字符串 |
void write(String str, int off, int len) | 写一个字符串的一部分 |
void write(char[] cbuf) | 写入一个字符数组 |
void write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
字符输出流管道对象的刷新与关闭
方法名称 | 说明 |
---|---|
public void flush() throws IOException | 刷新流,就是将内存中缓存的数据立即写到文件中去生效! |
public void close() throws IOException | 关闭流的操作,包含了刷新 |
为什么要刷新?
在管道里有内存缓冲区,不是每个字符都要和磁盘进行耦合,而是在内存缓冲区先集中一波,只做一次IO统一刷新到磁盘中。
刷新就是通知内存赶紧将缓冲区的数据全部写出去。
关闭包含了刷新!
缓冲流-提高性能
待更新