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():跨平台的换行
转换流:字符流和字节流之间的桥梁
字符转换输入流:InputStreamReader
字符转换输出流:OutputStreamWriter
作用1:指定字符集读写
作用2:字节流使用字符流中的方法
序列化流/对象操作输出流:
可以把Java中的对象写到本地文件中
构造方法:
public ObjectOutputStream(OutputStream out):把基本流包装成高级流
成员方法:
public final void writeObject(Object obj):把对象序列化到文件中去
细节:使用对象输出流将对象保存到文件中时会出现NotSerializableException异常
需要让Javabean类实现Serializable接口,Seralizable接口里没有抽象方法,标记型接口,一旦实现了这个接口,那么就表示当前的类可以被序列化
反序列化流/对象操作输入流:
可以把序列化到本地文件中的对象读取到程序中来
构造方法:
public ObjectInputStream(InputStream in):把基本流变成高级流
成员方法:
public Object readObject():把序列化到本地文件中的对象读取到程序中来
序列化流/反序列化流细节汇总:
1.使用序列化流将对象写到文件中时,需要让JavaBean类实现Serializable接口,否则会出现NotSerializableException异常
2.序列化流写到文件中的数据是不能修改的,一旦修改就无法改回来了
3.序列化对象后,修改了Javabean类,再次反序列化后会抛出InvaildClassException异常,可通过给Javabean类添加serialVersionUID解决
4.如果一个对象的某个成员变量的值不想被序列化,可以给该成员变量添加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
打印流:
分类:PrintStream,PrintWriter
特点:
1.打印流只操作文件目的地,不操作数据源
2.特有的写出方法可以实现,数据原样写出
字节打印流:
构造方法:
public PrintStream(OutputStream/File/String):关联字节输出流/文件/文件路径
public PrintStream(String fileName,Charset charset):指定字符编码
public PrintStream(OutputStream out,boolean autoFlush):自动刷新
public PrintStream(OutputStream out,boolean autoFlush,Sring encoding):指定字符集编码且自动刷新
成员方法:
public void write(int b):将指定的字节写出
public void println(Xxx xx):打印任意数据,自动刷新,自动换行
public void print(Xxxx xxx):打印任意数据,不换行
public void printf(String format,Object... args):带有占位符的打印语句,不换行
字符打印流:
字符流底层有缓冲区,想要自动刷新需要开启
构造方法:
public PrintWriter(Writer/File/String):关联字符输出流/文件/文件路径
public PrintWriter(String fileName,Charset charset):指定字符编码
public PrintWriter(Writer w,boolean autoFlush):自动刷新
public PrintWriter(OutputStream out,boolean autoFlush,Sring encoding):指定字符集编码且自动刷新
成员方法:
public void write(int b):将指定的字节写出
public void println(Xxx xx):打印任意数据,自动刷新,自动换行
public void print(Xxxx xxx):打印任意数据,不换行
public void printf(String format,Object... args):带有占位符的打印语句,不换行
解压缩流/压缩流ZipInputStream:
解压缩流:
把每一个ZipEntry按照层级拷贝到本地另一个文件夹中
需要先获取压缩包里面的每一个ZipEntry对象 zipinputstream.getNextEntry()
遇到文件夹时:需要在目的地dest处创建一个同样的文件夹
遇到文件时:需要读取到压缩包中的文件,并把它存放到目的地dest文件夹中
压缩流ZipOutputStream:
把每一个文件/文件夹看作ZipEntry对象放到压缩包中
压缩单个文件:
创建压缩流关流压缩包
创建ZipEntry对象,表示压缩包里面的每一个文件或文件夹
把ZipEntry对象放到压缩包当中
把src文件中的数据写到压缩包当中
压缩整个文件夹:
创建File对象表示要压缩的文件夹
创建File对象表示压缩包的存放路径(压缩包的父级路径)
创建File对象表示压缩包的路径
获取src中的每一个文件,变成ZipEntry对象,放入到压缩包当中
释放资源
Commons-io:
一组有关IO操作的开源工具包,可以提高IO流开发效率
使用步骤:
1.在项目中创建一个文件夹:lib
2.将jar包复制粘贴到lib文件夹中
3.右键点击jar包,选择add as library,点击OK
常见方法:
FileUtils类:
static void copyFile(File srcFile,File destFile):复制文件
static void copyDirectory(File srcDir,File destDir):复制文件夹
static void copyDirectoryToDirectory(File srcDir,File destDir):复制文件夹
static void deleteDirectory(File directory):删除文件夹
static void cleanDirectory(File directory):清空文件夹
static String readFileToString(File file,Charset encoding):以字符串读取文件中数据
static void write(File file,CharSquence data,String encoding):写出数据
IOUtils类:
public static int copy(InputStream input,OutputStream output):复制文件
public static int copyLarge(Reader input,Writer output):复制大文件
public static String readLines(Reader input):读取数据
public static void write(String data,OutputStream output):写出数据
Hutool工具包:
相关类 | 说明 |
IoUtil | 流操作工具类 |
FileUtil | 文件读写和操作的工具类 |
FileTypeUtil | 文件类型判断工具类 |
WatchMonitor | 目录、文件监听 |
ClassPathResource | 针对ClassPath中资源的访问封装 |
FileReader | 封装文件读取 |
FileWriter | 封装文件写入 |
FileUtil类:
file:根据参数创建一个file对象
touch:根据参数创建文件
writeLines:把集合中的数据写出到文件当中,覆盖模式
appendLines:把集合当中的数据写出倒文件中,续写模式
readLines:指定字符编码,把文件中的数据读到集合中
readUtf8Lines:按照UTF-8形式,把文件中的数据读到集合中
copy:拷贝文件或者文件夹