IO流,即文件的输入输出流,可以根据形式分为字节流和字符流。IO流的常用工具包有commons-io,hutool。
基本流
字节流用途更广泛,字符流可以解决字节流的乱码问题(判断字符集避免一个字分到不同字节)。
字节输出流(FileOutputStream)
写入文件,如果文件不存在,FileOutputStream会自动创建。
File file = new File("D:\\A.txt");
//加true为追加写入内容,不加会清空文件再写入
FileOutputStream outputStream = new FileOutputStream(file, true);
//或 FileOutputStream outputStream = new FileOutputStream("D:\\A.txt");
//写入数据
outputStream.write("你坏你坏".getBytes());
//关闭资源
outputStream.close();
异常优化后
//7版本后会自动关闭try()小括号中的资源
try (FileOutputStream outputStream = new FileOutputStream("D:\\A.txt");) {
outputStream.write("你坏你坏".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
字节输入流(FileInputStream)
读取文件,如果文件不存在,FileInputStream会抛出异常。
inputStream.read()只读一个字符,性能较差
FileInputStream inputStream = new FileInputStream("D:\\A.txt");
int i;
while ((i = inputStream.read()) != -1) {
System.out.println((char) i);
}
inputStream.close();
inputStream.read(b)会读出b容量的数据保存到b
FileInputStream inputStream = new FileInputStream("D:\\A.txt");
byte[] b = new byte[10];
while (inputStream.read(b) != -1) {
String string = new String(b);
System.out.println(string);
}
inputStream.close();
字符输入流(FileReader)
有8192字符的缓冲区
FileReader reader = new FileReader("D:\\A.txt");
// int i;
// while ((i=reader.read()) != -1){
// System.out.println((char) i);
// }
char[] chars = new char[1024];
int len;
while ((len=reader.read(chars)) != -1){
System.out.println(chars); //多余的长度会有null值
System.out.println(new String(chars,0,len));
}
reader.close();
字符输出流(FileWriter)
有缓冲区,调用flush或close方法,最后一部分才会从缓冲区写入文件。
//加true为追加写入内容,不加会清空文件再写入
FileWriter writer = new FileWriter("D:\\A.txt",true);
writer.write('a');
writer.write(new char[]{'a','b','c'});
writer.write(new char[]{'a','b','c'},0,2); //写入2个
writer.write("结束");
writer.write("结束",0,1); //写入1个
writer.close();
缓冲流
缓冲流不具备读写功能,只是对普通的流对象进行包装。
字节缓冲流
字节缓冲流内置了8192字节的缓冲区,可以提高读写效率。
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\A.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\B.txt"));
// int i;
// while ((i=bis.read()) != -1){
// bos.write(i);
// }
byte[] b = new byte[1024];
while (bis.read(b) != -1) {
bos.write(b);
}
bis.close();
bos.close();
字符缓冲流
字符缓冲流有一些易用的方法。
BufferedReader reader = new BufferedReader(new FileReader("D:\\A.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("D:\\B.txt"));
String line;
//readLine()读取一行数据
while ((line = reader.readLine()) != null){
System.out.println(line);
writer.write(line);
writer.newLine(); //newLine()可以在不同系统上换行
}
reader.close();
writer.close();
转换流
将字节流转换为字符流。
FileInputStream in = new FileInputStream("D:\\A.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in,"GBK"));
FileOutputStream out = new FileOutputStream("D:\\B.txt");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out,"GBK"));
br.close();
bw.close();
序列化流
序列化流可以读取或写入对象到文件中。
操作的对象所属类需要实现Serializable接口。并且需要定义好版本号serialVersionUID,否则修改类导致版本号的自动更改,无法读取以往保存的对象。
多个对象可以存入List来写入文件。
加 transient 的字段不参加序列化,存入List一样有效。
//写入文件
Student student = new Student("小林",22);
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("student.txt"));
outputStream.writeObject(student);
outputStream.close();
//读取文件
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("student.txt"));
Student o = (Student) inputStream.readObject();
System.out.println(o);
inputStream.close();
扩展:
序列化流可以方便的读写对象;
而util包下的Properties类可以方便的读写键值对数据,其继承于Hashtable。
打印流
PrintStream、PrintWriter 只能输出,System.out使用的就是PrintStream。
压缩流
对文件和文件夹进行压缩和解压缩操作,此处仅展示一个文件的读取和压缩。
读取压缩文件
ZipInputStream zip = new ZipInputStream(new FileInputStream("D:\\A.zip"));
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null){
if (entry.isDirectory()){
System.out.println(entry.toString());
} else {
System.out.println(entry.toString());
int b;
while ((b = zip.read()) != -1) System.out.println(b);
zip.closeEntry();
}
}
zip.close();
压缩文件
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(("D:\\"),"A.zip")));
FileInputStream fis = new FileInputStream("D:\\A.txt");
ZipEntry entry = new ZipEntry("a.txt");
zos.putNextEntry(entry);
int b;
while ((b = fis.read()) != -1) {
zos.write(b);
}
zos.closeEntry();
zos.close();
fis.close();