龙空技术网

Java IO流

Iliuhu 285

前言:

今天你们对“java流的关闭”都比较重视,兄弟们都想要剖析一些“java流的关闭”的相关文章。那么小编也在网上收集了一些对于“java流的关闭””的相关内容,希望姐妹们能喜欢,小伙伴们一起来学习一下吧!

IO流:随用随创建 不用要关闭IO流的作用IO流的分类IO流的体系FileOutputStreamimport java.io.FileOutputStream;import java.io.IOException;public class FileOutputStreamDemo { public static void main(String[] args) throws IOException { /* void write(byte[] b, int off, int len) 参数一:数组 参数二:起始索引 参数三:个数 */ // 创建字节输出流对象 FileOutputStream fos = new FileOutputStream("a.txt"); // 写出数据 byte[] bytes = {97,98,99,100,101}; /* bytes: 数组 off: 起始索引 len: 个数 */ fos.write(bytes, 1, 2); // 释放资源 fos.close(); }}FileInputStream

read:表示读取数据,而且读取一个数据就移动一次指针

一次读写一个字节import java.io.FileInputStream;import java.io.IOException;public class FileInputStreamDemo { public static void main(String[] args) throws IOException { // 创建流对象 FileInputStream fis = new FileInputStream("a.txt"); // 循环读取 // read: 表示读取数据,而且是读取一个数据就移动一次指针 int b; while (( b = fis.read()) != -1 ) { // 在循环判断中读过了,所以在循环体中就不需要再读了 System.out.println((char)b); } // 释放资源 fis.close(); }}一次读写多个字节

》》》如果每次读取的字节数组不指定个数(len),导致最后读取的结果会有问题

问题:每次读取的字节都会覆盖前一次的结果,可能导致最后读取的结果有问题

》》》解决方案:每次读取数组指定个数(len)

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class FileInOutputStreamDemo { public static void main(String[] args) throws IOException { // 创建流对象 FileInputStream fis = new FileInputStream("a.txt"); FileOutputStream fos = new FileOutputStream("b.txt"); // 拷贝 int len; // 个数 // 一次读取多个字节数 byte[] bytes = new byte[1024 * 1024 * 5]; while (( len = fis.read()) != -1 ) { // 每次读取字节,需加上个数(len),避免最后读取结果出现问题 fos.write(bytes, 0, len); } // 释放资源(先开先关闭) fos.close(); fis.close(); }}异常处理import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class FileInOutputStreamDemo { public static void main(String[] args) throws FileNotFoundException { // 创建流对象 FileInputStream fis = new FileInputStream("a.txt"); FileOutputStream fos = new FileOutputStream("b.txt"); try (fis; fos) { // 拷贝 int len; // 个数 // 一次读取多个字节数 byte[] bytes = new byte[1024 * 1024 * 5]; while (( len = fis.read()) != -1 ) { // 每次读取字节,需加上个数(len),避免最后读取结果出现问题 fos.write(bytes, 0, len); } } catch (IOException e) { e.printStackTrace(); } }}字符集ASCIIGBK:两个字节UnicodeUTF-8:三个字节乱码原因避免产生乱码import java.io.UnsupportedEncodingException;import java.util.Arrays;public class EncodeDecode { public static void main(String[] args) throws UnsupportedEncodingException { /* 编码方式: public byte[] getBytes() 默认方式 public byte[] getBytes(String charsetName) 指定方式进行编码 解码方式: String(byte[] bytes) 默认方式 String(byte[] bytes, String charsetName) 指定方式解码 */ // 编码 String str = "你好啊"; byte[] bytes01 = str.getBytes(); System.out.println(Arrays.toString(bytes01)); byte[] bytes02 = str.getBytes("GBK"); System.out.println(Arrays.toString(bytes02)); System.out.println("================================================"); // 解码 String str2 = new String(bytes01); System.out.println("bytes01 str2: " + str2); String str3 = new String(bytes01, "GBK"); // 编码和解码不一致,导致乱码 System.out.println("bytes01 str3: " + str3); System.out.println("================================================"); String str4 = new String(bytes02, "GBK"); System.out.println("bytes02 str4: " + str4); }}字符流FileReaderimport java.io.FileReader;import java.io.IOException;public class FileReaderDemo { public static void main(String[] args) throws IOException { // 创建对象并关联本地文件 FileReader fr = new FileReader("a.txt"); // 无参读取数据 // 字符流的底层也是字节流,默认也是一个字节一个字节的读取 // 遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节 // 读取之后,方法的底层还会进行解码并转成十进制,最后将十进制作为返回值 // 英文和中文: 文件里面的二进制数据,通过read方法进行读取,解码并转成十进制// int ch;// while ((ch = fr.read()) != -1) {// // 将十进制数据,强转成中文// System.out.println((char) ch);// } // 有参读取数据 char[] chs = new char[2]; int len; // read(chs): 读取数据、解码、强转三步合并了,把强转之后的字符放到数组当中 while ((len = fr.read(chs)) != -1) { // 把数组中的数据变成字符串再进行打印 System.out.println(new String(chs, 0, len)); } // 释放资源 fr.close(); }}FileWriter

根据字符集的编码方式进行编码,把编码之后的数据写到文件中去

import java.io.FileWriter;import java.io.IOException;public class FileWriterDemo { public static void main(String[] args) throws IOException { // 创建对象 FileWriter fw = new FileWriter("b.txt", true); // 写数据 char[] chars = {'a', 'b', 'c', 'd', 'e', 'f','我'}; fw.write(chars); // 释放资源 fw.close(); }}字符输入流原理import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class FileReaderWriterDemo { public static void main(String[] args) throws IOException { // 创建对象 FileReader fr = new FileReader("b.txt"); fr.read(); // 会把文件中的数据放到缓冲区当中 // 清空文件,不会清空缓冲区的数据(**特别注意**) FileWriter fw = new FileWriter("b.txt"); int ch; while ((ch = fr.read()) != -1) { System.out.println((char)ch); // 读的是缓冲区的数据 } // 释放资源 fw.close(); fr.close(); }}字符输出流原理

装满了、flush、close都会把数据放到目的地

文件拷贝import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class CopyFile { public static void main(String[] args) throws IOException { // 1. 创建源对象 File src = new File("D:\\aaa\\src"); // 2. 创建对象表示目的地 File dest = new File("D:\\aaa\\dest"); // 3. 调用方法开始拷贝 copydir(src, dest); } private static void copydir(File src, File dest) throws IOException { dest.mkdirs(); // 如果文件夹不存在,就创建,文件存在,也不会报错。 // 递归 // 进入数据源 File[] files = src.listFiles(); // 遍历数组 for (File file : files) { if (file.isFile()) { // 判断是文件,拷贝 FileInputStream fis = new FileInputStream(file); // 文件拷贝到目的地 FileOutputStream fos = new FileOutputStream(new File(dest, file.getName())); byte[] bytes = new byte[1024]; int len; while ((len = fis.read(bytes)) != -1) { fos.write(bytes, 0, len); } fos.close(); fis.close(); } else { // 判断文件夹,递归 // dest文件夹没有需提前创建 copydir(file, new File(dest, file.getName())); } } }}修改文件中数据方式一import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;import java.util.stream.Collectors;public class OrderContextFile { public static void main(String[] args) throws IOException { // 2-1-9-4-7-8 // 读取数据 FileReader fr = new FileReader("a.txt"); StringBuilder sb = new StringBuilder(); int ch; while ((ch = fr.read()) != -1) { sb.append((char)ch); } // 释放资源 fr.close(); String str = sb.toString(); String[] arrStr = str.split("-"); ArrayList<Integer> list = new ArrayList<Integer>(); for (String s : arrStr) { int i = Integer.parseInt(s); list.add(i); } // 排序 Collectors.sort(list); // 写出数据 FileWriter fw = new FileWriter("b.txt"); for (int i = 0; i < list.size(); i++) { if (i == list.size() - 1) { fw.write(list.get(i) + ""); // "" 数字转成字符串,能保证原样输出 } else { fw.write(list.get(i) + "-"); } } // 释放资源 fw.close(); }}方式二import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.Arrays;/* ①文件中的数据不要换行,②开头不要有bom头,否则会影响数据的结果。 */public class OrderContextFile { public static void main(String[] args) throws IOException { // 2-1-9-4-7-8 // 读取数据 FileReader fr = new FileReader("a.txt"); StringBuilder sb = new StringBuilder(); int ch; while ((ch = fr.read()) != -1) { sb.append((char)ch); } // 释放资源 fr.close(); // 使用流 Integer[] arr = Arrays.stream(sb.toString().split("-")/*切割之后为字符串数组*/) .map(Integer::parseInt) .sorted() .toArray(Integer[]::new); // 写出 FileWriter fw = new FileWriter("a.txt"); String s = Arrays.toString(arr).replace(",", "-"); // 数组 // 字符串截取前后的[] String result = s.substring(1, s.length() - 1); fw.write(result); // 释放资源 fw.close(); }}缓冲流字节缓冲流import java.io.*;public class BufferedStreamDemo { public static void main(String[] args) throws IOException { // 创建缓冲流对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt")); // 循环读取并写到目的地 // 拷贝(一次读写多个字节) byte[] bytes = new byte[1024]; int len; while ((len = bis.read()) != -1) { bos.write(bytes, 0, len); } // 释放资源 bos.close(); bis.close(); }}字符缓冲流原理字符缓冲流import java.io.*;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;/* 第一种方法: 给a.txt的内容排序,然后输出 a.txt : 4. hello 3. Hi 1. world 2. java */public class BufferedStreamDemo { public static void main(String[] args) throws IOException { // 读取数据 BufferedReader br = new BufferedReader(new FileReader("a.txt")); ArrayList<String> list = new ArrayList<>(); String line; while ((line = br.readLine()) != null) { list.add(line); } br.close(); // 排序:按照每一行前面的序号进行排列 Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { // 获取o1和o2的序号 int i1 = Integer.parseInt(o1.split("\\.")[0]); int i2 = Integer.parseInt(o2.split("\\.")[0]); return i1 - i2; } }); //写出 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); for (String str : list) { bw.write(str); bw.newLine(); // 换行 } // 释放资源 bw.close(); }}import java.io.*;import java.util.Map;import java.util.Set;import java.util.TreeMap;/* 第二种方法: 给a.txt的内容排序,然后输出 a.txt : 4. hello 3. Hi 1. world 2. java */public class BufferedStreamDemo { public static void main(String[] args) throws IOException { // 读取数据 BufferedReader br = new BufferedReader(new FileReader("a.txt")); // TreeMap可以自动排序 TreeMap<Integer, String> treeMap = new TreeMap<>(); String line; while ((line = br.readLine()) != null) { String[] arr = line.split("\\."); treeMap.put(Integer.parseInt(arr[0]), line); } br.close(); //写出 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); Set<Map.Entry<Integer, String>> entries = treeMap.entrySet(); for (Map.Entry<Integer, String> entry : entries) { bw.write(entry.getValue()); bw.newLine(); } // 释放资源 bw.close(); }}import java.io.*;/* 实现一个验证运行次数的小程序 不能定义count变量,因为变量在内存运行之后会消失的,所以计数器的变量保存在文件中永久性存储 */public class BufferedStreamDemo { public static void main(String[] args) throws IOException { // 把文件中的数字读取到内存中 BufferedReader br = new BufferedReader(new FileReader("count.txt")); String line = br.readLine(); int count = Integer.parseInt(line); count++; // 判断 if (count <=3) { System.out.println("第"+ count +"次免费使用"); } else { System.out.println("软件超过3次免费使用,请注册!!!"); } // 自增count值要写入文件中 BufferedWriter bw = new BufferedWriter(new FileWriter("count.txt")); bw.write(count + ""); // 加上""后,count的值是以字符串写入文件,避免数字发生转换 bw.close(); br.close(); }}转换流import java.io.*;import java.nio.charset.Charset;public class ConvertStreamDemo { public static void main(String[] args) throws IOException { // 利用转换流按照指定字符编码读取 // 创建对象并指定字符编码// InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "GBK");//// // 读取数据// int ch;//// while ((ch = isr.read()) != -1) {// System.out.println((char)ch);// }//// // 释放资源// isr.close(); // JDK11 替代方案 FileReader fr = new FileReader("a.txt", Charset.forName("GBK")); // 读取数据 int ch; while ((ch = fr.read()) != -1) { System.out.println((char)ch); } // 释放资源 fr.close(); }}import java.io.*;import java.nio.charset.Charset;public class ConvertStreamDemo { public static void main(String[] args) throws IOException { // 利用转换流按照指定字符编码写出 // 创建转换流的对象// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"), "GBK");//// // 写出数据// osw.write("你好你好");//// // 释放资源// osw.close(); // JDK11 替代方案 FileWriter fw = new FileWriter("b.txt", Charset.forName("GBK")); fw.write("你好你好"); fw.close(); }}import java.io.*;import java.nio.charset.Charset;public class ConvertStreamDemo { public static void main(String[] args) throws IOException { // 将本地文件的GBK文件,转成UTF-8 // JDK11以前的方案// InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "GBK");// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"), "UTF-8");//// int b;// while ((b = isr.read()) != -1) {// osw.write(b);// }//// osw.close();// isr.close(); // JDK11替代方案 FileReader fr = new FileReader("a.txt", Charset.forName("GBK")); FileWriter fw = new FileWriter("b.txt", Charset.forName("UTF-8")); int b; while ((b = fr.read()) != -1) { fw.write(b); } fr.close(); fw.close(); }}import java.io.*;public class ConvertStreamDemo { public static void main(String[] args) throws IOException { // 利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码 // 字节流在读取中文的时候,会出现乱码的,但是字符流可以搞定 // 字节流里卖弄是没有读一整行的方法,只有字符流缓冲流才能搞定 FileInputStream fis = new FileInputStream("a.txt"); InputStreamReader isr = new InputStreamReader(fis); // 读取一整行 BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); }}对象操作流

序列化/反序列化:数据读到最后会报EOFException。

注意:序列化/反序列化一定是先写后读。

序列化流import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;public class ObjectStreamDemo { public static void main(String[] args) throws IOException { // 创建对象 Student student = new Student("zhangsan", 23); // 创建序列化流的对象/对象操作输出流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")); // 写出数据 oos.writeObject(student); // 释放资源 oos.close(); }}反序列化流import java.io.*;public class ObjectStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { // 创建反序列化流的对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")); // 读取数据 Student student = (Student) ois.readObject(); // 打印对象 System.out.println("student = " + student); // 释放资源 ois.close(); }}import java.io.*;import java.util.ArrayList;public class ObjectStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { // 序列化多个对象 Student s1 = new Student("zhangsan", 23, "南京"); Student s2 = new Student("lisi", 24, "重庆"); Student s3 = new Student("wangwu", 26, "四川"); // 优化 ArrayList<Student> list = new ArrayList<>(); list.add(s1); list.add(s2); list.add(s3); // 创建序列化流对象 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")); // 缺点:如果序列化对象多少次未知,会导致反序列化报异常// oos.writeObject(s1);// oos.writeObject(s2);// oos.writeObject(s3); oos.writeObject(list); // 创建反序列化流对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));// Student stu1 = (Student) ois.readObject();// Student stu2 = (Student) ois.readObject();// Student stu3 = (Student) ois.readObject();// System.out.println("stu1 = " + stu1);// System.out.println("stu2 = " + stu2);// System.out.println("stu3 = " + stu3); // 优化 ArrayList<Student> students = (ArrayList<Student>) ois.readObject(); for (Student student : students) { System.out.println("student = " + student); } // 释放资源 ois.close(); oos.close(); }}打印流:只能打印字节打印流import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;import java.nio.charset.Charset;public class PrintStreamDemo { public static void main(String[] args) throws FileNotFoundException { // 创建打印流对象 PrintStream ps = new PrintStream(new FileOutputStream("a.txt"), true, Charset.forName("UTF-8")); // 写出数据 自动刷新 自动换行 ps.println(97); // 数据原样写出 ps.print("hello world!"); ps.printf("%s java", "hello"); // 释放资源 ps.close(); }}字符打印流import java.io.FileWriter;import java.io.IOException;import java.io.PrintStream;import java.io.PrintWriter;public class PrintWriterDemo { public static void main(String[] args) throws IOException { // 创建字符打印流对象 PrintWriter pw = new PrintWriter(new FileWriter("a.txt"), true); // 写出数据 pw.println("hello world"); // 特殊的打印流,系统中的标准输出流,是系统唯一的 PrintStream ps = System.out; ps.println("123"); // 释放资源 ps.close(); pw.close(); }}解/压缩流解压缩流import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;public class ZipStreamDemo { public static void main(String[] args) throws IOException { // 创建一个File的压缩包 File src = new File("aaa.zip"); // 创建一个File解压的目的地 File dest = new File("D:\\"); unzip(src, dest); } // 定义解压的方法 public static void unzip(File src, File dest) throws IOException { // 解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地中 // 创建一个解压缩流用来读取压缩包中的数据 ZipInputStream zip = new ZipInputStream(new FileInputStream(src)); // 先获取到压缩包中的每一个zipentry对象// ZipEntry entry1 = zip.getNextEntry(); // 获取文件和文件夹 ZipEntry entry; while ((entry = zip.getNextEntry()) != null) { if (entry.isDirectory()) { // 文件夹:在dest就要创建文件夹 File file = new File(dest, entry.toString()); // 在dest下创建文件夹 file.mkdirs(); } else { FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString())); // 文件:需读取文件中的内容,而且需放到对应的dest文件夹中(按层级目录存放) int b; while ((b = zip.read()) != -1) { // 写到目的地 fos.write(b); } fos.close(); // 压缩包中一个文件处理完毕了 zip.closeEntry(); } } // 释放资源 zip.close(); }}压缩流压缩单个文件import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream;public class ZipStreamDemo { public static void main(String[] args) throws IOException { // 创建File对象表示要压缩的文件 File src = new File("D:\\a.txt"); // 创建File对象表示压缩包的位置 File dest = new File("D:\\"); // 调用方法用来压缩 toZip(src, dest); } /** * 作用:压缩 * @param src 压缩的文件 * @param dest 压缩包的位置 */ public static void toZip(File src, File dest) throws IOException { // 创建压缩流关联压缩包 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest, "a.zip"))); // 创建ZipEntry对象,压缩包里面的每一个文件和文件夹 ZipEntry entry = new ZipEntry("a.txt"); // 把ZipEntry队形放到压缩包中 zos.putNextEntry(entry); // 把src文件中的数据写到压缩包中 FileInputStream fis = new FileInputStream(src); int b; while ((b = fis.read()) != -1) { zos.write(b); } // 释放资源 zos.closeEntry(); zos.close(); }}压缩文件夹import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream;public class ZipStreamDemo { public static void main(String[] args) throws IOException { // 创建File对象表示要压缩的文件 File src = new File("D:\\aaa"); // 创建File对象表示压缩包的位置 File destParent = src.getParentFile(); // 创建File对象表示压缩包的路径 File dest = new File(destParent, src.getName() + ".zip"); // 创建关联压缩包 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest)); // 获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中 toZip(src, zos, src.getName()); // 释放资源 zos.close(); } /** * 获取src里卖弄的每一个文件,变成ZipEntry对象,放入压缩包中 * @param src 数据源 * @param zos 压缩流 * @param name 压缩包内部的路径 * @throws IOException */ public static void toZip(File src, ZipOutputStream zos, String name) throws IOException { // 进入src文件夹 File[] files = src.listFiles(); // 遍历数组 for (File file : files) { // 文件,变成ZipEntry对象,放入到压缩包中 if (file.isFile()) { ZipEntry entry = new ZipEntry(name + "\\" + file.getName()); zos.putNextEntry(entry); // 读取文件中的数据,写到压缩包 FileInputStream fis = new FileInputStream(file); int b; while ((b = fis.read()) != -1) { zos.write(b); } fis.close(); zos.closeEntry(); } else { // 文件夹 toZip(file, zos, name + "\\" + file.getName()); } } }}Commons-io

import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;public class CommonsIODemo { public static void main(String[] args) throws IOException { File src1 = new File("a.txt"); File dest1 = new File("copy.txt"); FileUtils.copyFile(src1, dest1); // copy文件 File src2 = new File("D:\\aaa"); File dest2 = new File("D:\\eee"); FileUtils.copyDirectory(src2, dest2); // copy文件夹 File dest3 = new File("D:\\eee"); FileUtils.cleanDirectory(dest3); // 删除文件夹里面的文件 }}Hutoll工具包<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version></dependency>import cn.hutool.core.io.FileUtil;import java.io.File;import java.util.ArrayList;import java.util.List;public class HuToolDemo { public static void main(String[] args) { File file = FileUtil.file("D:\\","aaa","bbb","a.txt"); System.out.println(file); // D:\\aaa\\bbb\\a.txt File touch = FileUtil.touch(file); // 如果父级目录不存在,一并创建 ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); FileUtil.writeLines(list, "D:\\a.txt", "UTF-8", true); // 追加写入 FileUtil.appendLines(list, "D:\\a.txt", "UTF-8"); // 追加写入 List<String> linesList = FileUtil.readLines("D:\\a.txt", "UTF-8"); //一行的数据是集合的一个元素 }}

标签: #java流的关闭