IO流:
存储和读取数据的解决方案
File类只能对文件本身进行操作,不能读写文件里面存储的数据。
IO流用于读写文件中的数据
分类:
1.按照流的方向分类:
输入流:读取
输出流:写出
2.按照操作文件类型分类:
字节流:可以操作所有类型的文件
字符流:只能操作纯文本文件
IO流的体系:
字节流:
InputStream字节输入流
FileInputStream操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中
Step1:创建字节数据流对象 FileInputStream(待读取的本地文件路径名称)
1.如果文件路径对应的文件不存在,直接报错
Step2:读取数据 b = read()
1.一次读取一个字节,读取出来的是数据在ASCII上对应的数字
2.读到文件末尾时返回-1
3.一次读取多个字节: public int read(byte[] buffer),一次读取一个字节数组数据,每次读取会尽可能把数组装满,返回值表示本次读取的字节数目
Step3:释放资源
1.每次使用完毕后需要释放资源
可以使用循环读取整个文件中的全部数据
OutputStream字节输出流
FileOutputStream操作本地文件的字节输出流,可以把程序中的数据写到本地文件中
Step1:创建字节输出流对象 FileOutputStream(待写入的本地文件路径名称)
参数是字符串表示的路径或者是File对象都是可以的
如果路径对应的文件不存在会创建一个新的文件,但是要保证父级路径存在
如果文件已经存在,则会清空文件
Step2:写数据 fos.write(内容)
write方法实际上写到本地文件上的是整数对应的ASCII字符
Step3:释放资源 fos.close()
写数据的三种方式:
void write(int b):一次写一个字节数据
void write(byte[] b):一次写一个字节数组数据
void write(byte[] b,int off, int len):一次写一个字节数组的部分数据
off:起始索引
len:写入的个数
续写:创建字节输出流对象时传递一个参数true,表示打开续写开关,该参数默认为false,会清空文件重写
try...catch...finally异常处理:
finally里面的代码一定会被执行,除非虚拟机停止
基本做法:手动释放资源
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常处理代码;
}finally{
执行所有资源释放的操作;
}
JDK7方案:资源用完最终自动释放
try(创建流对象1;创建流对象2){
可能出现异常的代码;
}catch(异常类名 变量名){
异常处理代码;
}
JDK9方案:资源用完最终自动释放
创建流对象1;
创建流对象2;
try(流1;流2){
可能出现异常的代码;
}catch(异常类名 变量名){
异常处理代码;
}
字符集:
ASCII字符集:存储英文,一个字节即可
GB2312字符集
BIG5字符集
BGK字符集:系统显示ANSI,一个英文字母一个字节,二进制第一位是0;一个汉字使用两个字节进行存储,高位字节二进制一定以1开头
Unicode字符集:国际标准字符集
UTF-16编码规则:用2~4个字节保存
UTF-32编码规则:用固定的4个字节保存
UTF-8编码规则:用1~4个字节保存
乱码产生的原因:
1.读取数据时未读完整个汉字
2.编码和解码的方式不统一导致乱码
避免产生乱码:
1.不要使用字节流读取文件
2.编码和解码的方式要保持统一
Java中编码的方法:
public byte[] getBytes():使用默认方式进行编码
public byte[] getBytes(String charsetName):使用指定方式进行编码
Java中解码的方法:
String(byte[] bytes):使用默认方式进行解码
String(byte[] bytes,String charsetName):使用指定方式进行解码
字符流:
字符流 = 字节流 + 字符集
Reader字符输入流: 一次读取一个字节,遇到中文时一次读取多个字节
FileReader
1.创建字符输入流对象:
public FileReader(File file):创建字符输入流关联本地文件
public FileReader(String pathname):创建字符输入流关联本地文件
2.读取数据:
public int read():读取数据,读到末尾返回-1
public int read(char[] buffer):读取多个数据,读到末尾返回-1,返回读取的长度
按字节读取,遇到中文一次读取多个字节,读取后解码,返回一个整数
读到文件末尾返回-1
在读取之后底层会进行解码并转换成十进制,最终把这个十进制作为返回值
如果要看到中文,则需要对结果进行强制类型转换,将其转换为char类型即可
3.释放资源:
public int close():释放资源/关流
Writer字符输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
FileWriter
构造方法:
public FileWriter(File file):创建字符输出流关联本地文件
public FileWriter(String pathname):创建字符输出流关联本地文件
public FileWriter(File file,boolean append):创建字符输出流关联本地文件,续写
public FileWriter(String pathname,boolean append):创建字符输出流关联本地文件,续写
成员方法:
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):写出字符数组的一部分
1.创建字符输出流对象:
参数是字符串表示的路径或者File对象
如果文件不存在会创建一个新的文件,但要保证父级路径是存在的
如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
2.写数据:
如果write方法的参数是整数,但是实际上写到本地文件中的是对应编码方式的字符
3.释放资源:
每次使用完流之后都要释放资源
缓冲流:
字节缓冲流:底层自带长度为8192的缓冲区提高性能
字节缓冲输入流BufferedInputStream
public BufferedInputstream(InputStream is):把基本流包装成高级流,提高读取数据性能
字节缓冲输出流BufferedOutputStream
public BufferedOutputstream(OutputStream os):把基本流包装成高级流,提高写出数据性能
字符缓冲流:底层自带长度为8192的缓冲区提高性能,提升性能不如字节缓冲流
字符缓冲输入流BufferedReader
public BufferedReader(Reader r):把基本流包装成高级流
字符缓冲输出流BufferedWriter
public BufferedWriter(Writer r):把基本流包装成高级流
特有方法:
public String readLine():读取一行数据,如果没有数据可读会返回null,遇到回车换行就会结束,同时不会读取回车换行
public void newLine():跨平台的换行