顶层父类:
java.io.OutputStream 字节输入流
java.io.InputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
换行符号:
windows: \r\n
linux: \n
mac: \r
使用字节流读取中文文件:
1个中文
GBK(中文码表): 占用2个字节
UTF-8(国际标准码表): 占用3个字节
IO流的选取:
字节输入流:InputStream 所有字节输入流的父类
- FileInputStream:字节非缓冲输入流,效率低,不推荐直接使用
- BufferedInputStream:字节缓冲输入流,效率高,推荐使用
- ObjectInputStream:对象输入流,当需要从文件中读取自定义对象时使用
字节输出流:OutputStream 所有字节输出流的父类
- FileOutputStream:字节非缓冲输出流 效率低,不推荐直接使用
- BufferedOutputStream:字节缓冲输出流,效率高,推荐使用
- ObjectOutputStream:对象输出流,当需要保存自定义对象到文件中时使用
- PrintStream:字节打印流,当希望原样输出各种数据类型的值时使用
字符输入流:Reader 所有字符输入流的父类
- FileReader:字符非缓冲输入流,效率低,不推荐直接使用
- BufferedReader:字符缓冲输入流,效率高,推荐使用
- InputStreamReader:字符转换输入流,当需要修改默认码表去读数据时使用
字符输出流:Writer 所有字符输出流的父类
- FileWriter:字符非缓冲输出流 ,效率低,不推荐直接使用
- BufferedWriter:字符缓冲输出流,效率高,推荐使用
- OutputStreamWriter:字符转换输出流,当需要修改码表去输出数据时使用
- PrintWriter:字符打印流,当希望原样输出各种数据类型的值时使用
如何选择流
如果清楚要操作的文件类型是文本文件,则强烈推荐字符流。
如果不清楚要操作的文件类型是什么类型的,则只能选择字节流
OutputStream 字节输出流
子类共性的成员方法:
public void close()
public void flush()
public void write(byte[] b)
public void write(byte[] b,int off,int len)
public abstract void write(int b)
写入数据的原理(内存-->硬盘):
java程序-->JVM-->OS-->OS调用写数据的方法-->把数据写入文件中
java.io.FileOutputStream extends OutputStream
FileOutputStream文件字节输出流
作用:把内存中的数据写到硬盘中
构造方法:(作用相同)
FileOutputStream(String name) 创建一个向 具有指定名称的文件 中写入数据的输出文件流
FileOutputStream(File file) 创建一个向 指定File对象表示的文件 中写入数据的文件输出流
追加写(续写)使用两个参数的构造方法
FileOutputStream(String name,boolean append)
FileOutputStream(File file,boolean append)
boolean append:追加写开关
true: 创建对象不会覆盖源文件,继续在文件末尾追加写数据
false: 创建一个新文件,覆盖文件
字节输出流使用步骤:
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2.使用FileOutputStream对象中的方法write,把数据写入到文件中
3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提高程序效率)
写入字符的方法:可以使用String类中的方法,把字符串转换为字节数组
byte[] getBytes()
windows输入换行: fos.write("\r\n".getBytes());
InputStream 字节输入流
子类共性成员方法:
int read()
int read(byte[] b)
void close()
读取数据的原理(硬盘-->内存):
java程序-->JVM-->OS-->OS调用读取数据的方法-->读取文件
java.io.FileInputStream extends InputStream
FileInputStream文件字节输入流
作用:把硬盘中的数据读取到内存中使用
构造方法:
FileInputStream(String name)
FileInputStream(File file)
字节输出流使用步骤:
1.创建一个FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取文件
3.释放资源
字节输入流一次读取多个字节的方法:
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
1.方法的参数byte[]起到缓冲作用,存储每次读到的多个字节.(长度一般定义为1024或1024的整数倍)
2.int返回值是每次读取的有效字节个数
读取字符的方法:使用String类的构造方法:
String(byte[] bytes) 把字节数组转换为字符串
String(byte[] bytes,int offest,int length) 把字节数组的一部分转换为字符串
Reader 字符输入流
子类共性成员方法:
int read()
int read(char[] cbuf)
void close()
java.io.FileReader extends InputStreamReader extends Reader
FileReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FileReader(String fileName)
FileReader(File file)
字符输入流的使用步骤:
1.创建FileReader对象,构造方法中绑定要读取的数据源
2.使用FileReader对象中的方法read读取文件
3.释放资源
Writer 字符输出流
子类共性成员方法:
void write(int c)
void write(char[] cbuf)
abstract void write(char[] cbuf,int off,int len)
void write(String str)
void write(String str,int off,int len)
void flush()
void close()
java.io.FileWriter extends OutputStreamWriter extends Writer
FileWriter:文件字符输出流
作用:把内存中字符数据写入到文件中
构造方法;
FileWriter(File file)
FileWriter(String filename)
追加写(续写)使用两个参数的构造方法(同字节输出流)
FileWriter(String fileName,boolean append)
FileWriter(File file,boolean append)
boolean append:追加写开关
true: 创建对象不会覆盖源文件,继续在文件末尾追加写数据
false: 创建一个新文件,覆盖文件
注意:字符输出流与字节输出流最大的区别:
字节输出流可以将数据直接写入文件,
字符输出流需要先将文件写入内存缓冲区(字符转换为字节)
再用flush将缓冲区中数据刷新到文件中
字符输出流的使用步骤:
1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
2.使用FileWriter中的write方法,把数据写入到内存缓冲区中(字符转换为字节的过程)
3.使用FileWriter中的flush方法,将内存缓冲区中的数据,刷新到文件中
4.释放资源
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。
但是关闭流对象后,就无法继续写出数据。
如果既想写出数据,又想继续使用流,就要使用flush方法
flush方法和close方法的区别;
flush: 刷新缓冲区,流对象可以继续使用
close: 先刷新缓冲区,然后通知系统释放资源,流对象不可以再被使用了
JDK7的新特性:
在try后可增加一个(),在括号中可以定义流对象
这个流对象的作用于就在try中有效
try中的代码执行完毕,会自动把流对象释放,不用写finally
格式:
try(定义流对象;定义流对象...){
可能出现异常的代码
}catch(异常类型名 常量名){
异常的处理逻辑
}
JDK9的新特性:
try的前边可以定义流对象
在try后的()中可以直接引入流对象的名称(变量名)
在try代码执行完毕之后,流对象也可以释放掉,不用写finally
格式:
A a = new A();
B b = new B();
try(a,b){
可能会出现异常的代码
}catch(异常类变量 变量名){
异常的处理逻辑
}