当前位置: 首页 > news >正文

IO 字符流 【详解】| Java 学习日志 | 第 13 天

目录

        FileReader

        FileWriter

        字符流底层原理

        字节缓冲流

        字符缓冲流

        转换流

        序列化流 / 反序列化流

        打印流

        解压缩流 / 压缩流

        Commons-io工具包

        Hutool


        回顾之前的乱码问题,其中一个原因是读取数据时没有完整地读取一个汉字所需的字节数。字符流可以解决问题。

        字符流包含Reader,Writer两个抽象类

        FileReader

        第一步:创建对象
        public FileReader(File file)        创建字符输入流关联本地文件
        public FileReader(String pathname)  创建字符输入流关联本地文件

        第二步:读取数据
        public int read()                   读取数据,读到末尾返回-1
        public int read(char[] buffer)      读取多个数据,读到末尾返回-1

        第三步:释放资源
        public void close()                 释放资源/关流

        空参构造。

        注意read返回的是int要转成char。

public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");int c;while((c = fr.read()) != -1) {System.out.println((char) c);}

        有参构造,要用new String构造方法强转。

public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");int len;char[] c = new char[2];while((len = fr.read(c)) != -1) {System.out.print(new String(c, 0, len));}}

        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)   写出字符数组的一部分

       第三步:释放资源
       public void close()                 释放资源/关流

public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("a.txt");fw.write(25105);fw.write(42227);fw.write("你好威啊???");char[] chars = {'a','b','c','我'};fw.write(chars);fw.close();fw.close();}

        字符流底层原理

        创建字符输入流对象,关联文件并创建缓冲区(长度为8192B的byte数组)

        获取数据时,判断缓冲区中是否有数据,有就从缓冲区中获取,没有就从文件中获取尽可能装满缓冲区。空参read一次读一个字符,把字节解码并转成十进制返回,有参read将读取字节,解码,强转合并了,最后存放数组中。

        Debug读代码。

        可以看到图中创建了一个大小8192​​B的缓冲区。

        read会把数据放入缓冲区,这里创建FileWriter虽然会清空文件但不会清空缓冲区,缓冲区大小的数据依然能读取。

public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");fr.read();//会把文件中的数据放到缓冲区当中//清空文件FileWriter fw = new FileWriter("a.txt");//请问,如果我再次使用fr进行读取//会读取到数据吗?//会把缓冲区中的数据全部读取完毕//正确答案://但是只能读取缓冲区中的数据,文件中剩余的数据无法再次读取int ch;while((ch = fr.read()) != -1){System.out.println((char)ch);}fw.close();fr.close();}

        字节流可以拷贝任意文件的数据,字符流只能读取和写纯文本文件。

        练习:拷贝文件夹。

        拷贝文件夹四步走,1.进入文件夹,2.遍历文件夹,3.判断文件,拷贝,4.判断文件夹,递归。

public static void main(String[] args) throws IOException {//拷贝一个文件夹,考虑子文件夹//1.创建对象表示数据源File src = new File("D");//2.创建对象表示目的地File dest = new File("B");//3.调用方法开始拷贝copydir(src,dest);}/** 作用:拷贝文件夹* 参数一:数据源(文件夹)* 参数二:目的地(文件夹)** */private static void copydir(File src, File dest) throws IOException {//创建文件夹dest.mkdirs();//递归//1.进入数据源File[] files = src.listFiles();//2.遍历数组for (File file : files) {if (file.isFile()) {//3.判断文件,拷贝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 {//4.判断文件夹,递归//创建文件夹放入新的文件夹中copydir(file, new File(dest, file.getName()));}}}

        练习:加密解密文件,利用异或的性质。

public static void main(String[] args) throws IOException {//加密FileInputStream fis = new FileInputStream("1.jpg");FileOutputStream fos = new FileOutputStream("2.jpg");int b;while((b = fis.read()) != -1){fos.write(b ^ 2);}fos.close();fis.close();//解密FileInputStream fis1 = new FileInputStream("2.jpg");FileOutputStream fos1 = new FileOutputStream("3.jpg");int b1;while((b1 = fis1.read()) != -1){fos1.write(b1 ^ 2);}fos1.close();fis1.close();}

        练习:排序文件中的数据

    public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");StringBuilder sb = new StringBuilder();int c;while ((c = fr.read()) != -1) {sb.append((char) c);}fr.close();System.out.println(sb);FileWriter fw = new FileWriter("b.txt");String[] arr = sb.toString().split("-");ArrayList<Integer> arrayList = new ArrayList<>();for (String s : arr) {arrayList.add(Integer.parseInt(s));}Collections.sort(arrayList);for (int i = 0; i < arrayList.size(); i++) {if(i != arrayList.size() - 1) {fw.write(arrayList.get(i) + "-");} else {fw.write(arrayList.get(i) + "");}}fw.close();Integer[] arrs = Arrays.stream(sb.toString().split("-")).map(Integer::parseInt).sorted().toArray(Integer[]::new);String s1 = Arrays.toString(arrs).replace(", ", "-");String s2 = s1.substring(1, s1.length() - 1);System.out.println(s2);fw.write(s2);fw.close();}

        字节缓冲流

        创建缓冲流对象:
        public BufferedInputStream(InputStream is)        字节缓冲输入流的构造方法
        public BufferedOutputStream(OutputStream os) 字节缓冲输出流的构造方法

        拷贝文件,一次读取一个字节。

public static void main(String[] args) throws IOException {//1.创建缓冲流的对象BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));int b = bis.read();BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));//2.循环读取并写到目的地bos.write(b);while ((b = bis.read()) != -1) {bos.write(b);}//3.释放资源内置了基本流的释放bos.close();bis.close();
}

        拷贝文件,一次读取多个字节。

public static void main(String[] args) throws IOException {BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream("a.txt"));int b1 = bis1.read();BufferedOutputStream bos1 = new BufferedOutputStream(new                                    FileOutputStream("a.txt"));bos1.write(b1);//2.循环读取并写到目的地byte[] bytes = new byte[2];int len;while ((len = bis1.read(bytes)) != -1) {bos1.write(bytes);}//3.释放资源内置了基本流的释放bos1.close();bis1.close();
}

        字节缓冲流提高效率的原理

        字节缓冲输入流和输出流分别会在内存中创建个自己的8192B大小的缓冲区,而读取的数据从输入流的缓冲区读取数据,写数据会写到输出流的缓冲区,由于这些操作在内存中所以效率很高。

        字符缓冲流

        字符基本流已经具备缓冲区,字符缓冲流提供了新的方法。

        字符缓冲流自带长度为8192的缓冲区(不一样的是类型char类型2字节)。

        字符缓冲输入流:

        public BufferedReader(Reader r)         构造方法

        public String readLine()                        读一整行 特有方法

        readLine方法在读取的时候,一次读一整行,遇到回车换行结束 // 但是他不会把回车换行读到内存当中。
         字符缓冲输出流:
         public BufferedWriter(Writer r)             构造方法
         public void newLine()                           跨平台的换行  特有方法 

public static void main(String[] args) throws IOException {//1.创建字符缓冲输入流的对象BufferedReader br = new BufferedReader(new FileReader("a.txt"));//2.读取数据String line;while ((( line = br.readLine()) != null)){System.out.println(line);}//3.释放资源br.close();//1.创建字符缓冲输出流的对象BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt",true));//2.写出数据bw.write("123");bw.newLine();bw.write("111");bw.newLine();//3.释放资源bw.close();}

        练习:按照每一行前面的序号进行排列。

        方法一:ArrayList使用Collections调用Comparator排序。

public static void main(String[] args) throws IOException {//1.读取数据BufferedReader br = new BufferedReader(new FileReader("a.txt"));String line;ArrayList<String> list = new ArrayList<>();while((line = br.readLine()) != null){list.add(line);}br.close();//2.排序//排序规则:按照每一行前面的序号进行排列Collections.sort(list, new Comparator<String>() {@Overridepublic 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;}});//3.写出BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));for (String str : list) {bw.write(str);bw.newLine();}bw.close();}

        方法二,使用TreeMap集合排序

public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("a.txt"));String line;TreeMap<Integer, String> tm = new TreeMap<>();while((line = br.readLine()) != null){Integer n = Integer.parseInt(line.split("\\.")[0]);tm.put(n, line);}BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));for (Map.Entry<Integer, String> entry : tm.entrySet()) {bw.write(entry.getValue());bw.newLine();}bw.close();}

        练习:记录程序的使用次数。

public static void main(String[] args) throws IOException {//1.把文件中的数字读取到内存中//原则://IO:随用随创建//    什么时候不用什么时候关闭BufferedReader br = new BufferedReader(new FileReader("b.txt"));String line = br.readLine();br.close();int count = Integer.parseInt(line);//表示当前软件又运行了一次count++;//1//2.判断if(count <= 3){System.out.println("欢迎使用本软件,第"+count+"次使用免费~");}else{System.out.println("本软件只能免费使用3次,欢迎您注册会员后继续使用~");}BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));//3.把当前自增之后的count写出到文件当中bw.write(count + ""); //97 + ""bw.close();}

        转换流

        转换流属于字符流,包含字符转化输入流InputStreamReader,字符转化输出流OutputStreamWriter。

        转换流是字节流和字符流的桥梁。

        读取一个ANSI编码的文件也就是GBK编码的文件。

public static void main(String[] args) throws IOException {/*利用转换流按照指定字符编码读取(了解)因为JDK11:这种方式被淘汰了。替代方案(掌握)F:\JavaSE最新版\day29-IO(其他流)\资料\gbkfile.txt*//* //1.创建对象并指定字符编码InputStreamReader isr = new InputStreamReader(new FileInputStream("myio\\gbkfile.txt"),"GBK");//2.读取数据int ch;while ((ch = isr.read()) != -1){System.out.print((char)ch);}//3.释放资源isr.close();*/FileReader fr = new FileReader("D:\\新建文件夹\\aaa.txt", Charset.forName("GBK"));//2.读取数据int ch;while ((ch = fr.read()) != -1){System.out.print((char)ch);}//3.释放资源fr.close();}

        指定字符编码写出。

public static void main(String[] args) throws IOException {/*利用转换流按照指定字符编码写出*//*//1.创建转换流的对象OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myio\\b.txt"),"GBK");//2.写出数据osw.write("你好你好");//3.释放资源osw.close();*/FileWriter fw = new FileWriter("c.txt", Charset.forName("GBK"));fw.write("你好你好");fw.close();}

        将上一次写入的GBK编码文本文件读出并转化为UTF-8编码。

public static void main(String[] args) throws IOException {/*将本地文件中的GBK文件,转成UTF-8*///1.JDK11以前的方案/* InputStreamReader isr = new InputStreamReader(new FileInputStream("myio\\b.txt"),"GBK");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myio\\d.txt"),"UTF-8");int b;while((b = isr.read()) != -1){osw.write(b);}osw.close();isr.close();*///2.替代方案FileReader fr = new FileReader("c.txt", Charset.forName("GBK"));FileWriter fw = new FileWriter("e.txt",Charset.forName("UTF-8"));int b;while ((b = fr.read()) != -1){fw.write(b);}fw.close();fr.close();}

        使用转化流可以使字节流变为字符流。

public static void main(String[] args) throws IOException {/*利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码//1.字节流在读取中文的时候,是会出现乱码的,但是字符流可以搞定//2.字节流里面是没有读一整行的方法的,只有字符缓冲流才能搞定*//* FileInputStream fis = new FileInputStream("myio\\a.txt");InputStreamReader isr = new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);String str = br.readLine();System.out.println(str);br.close();*///字符流(转换流(字节流)))BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));String line;while ((line = br.readLine()) != null){System.out.println(line);}br.close();}

        序列化流 / 反序列化流

        序列化流ObjectOutputStream,可以把java中的对象写到本地文件中,又名对象操作输出流。

        构造方法:
                public ObjectOutputStream(OutputStream out)         把基本流变成高级流

        成员方法:
                public final void writeObject(Object obj)           把对象序列化(写出)到文件中去

        对象类需要implements Serializable标记型接口。

class People implements Serializable {String name;int age;public People(String name, int age) {this.name = name;this.age = age;}
}
public class ObjectIO {public static void main(String[] args) throws IOException {//1.创建对象People p = new People("ai",18);//2.创建序列化流的对象/对象操作输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));//3.写出数据oos.writeObject(p);//4.释放资源oos.close();}
}

        反序列化流ObjectInputStream,又名对象操作输入流。

        构造方法:
                public ObjectInputStream(InputStream out)         把基本流变成高级流
        成员方法:
                public Object readObject()             把序列化到本地文件中的对象,读取到程序中来

class People implements Serializable {String name;int age;public People(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "People{" +"name='" + name + '\'' +", age=" + age +'}';}
}
public class ObjectIO {public static void main(String[] args) throws IOException, ClassNotFoundException {//1.创建反序列化流的对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));//2.读取数据People p = (People) ois.readObject();//3.打印对象System.out.println(p);//4.释放资源ois.close();}
}

        修改类中的内容会改变类的版本号(版本号计算类的所有内容得到的),读取类对象的时候会验证版本号,所以我们需要固定版本号。勾选idea中两个选项Java | Serialization issues | Transient field is not initialized on deserialization,JVM languages | Serializable class without 'serialVersionUID'。这样会提示添加UID,自动生成UID。

        这样设置后修改了对象类但是依然能读出文件数据。

class People implements Serializable {private static final long serialVersionUID = 454348404180664668L;String name;int age;String w;public People(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "People{" +"name='" + name + '\'' +", age=" + age +", w=" + w +'}';}
}
public class ObjectIO {public static void main(String[] args) throws IOException, ClassNotFoundException {//1.创建反序列化流的对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));//2.读取数据People p = (People) ois.readObject();//3.打印对象System.out.println(p);//4.释放资源ois.close();}
}

        如果一个对象中的某个成员变量的值不想被序列化,可以给成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程。

        序列化多个对象。

        由于将多个对象序列化到文件中的个数是不确定的,为了防止读取时发生超出边界的EOF的异常,我们使用集合存储对象写入读取。

public static void main(String[] args) throws IOException, ClassNotFoundException {People p1 = new People("1", 17, "2");People p2 = new People("1", 17, "2");People p3 = new People("1", 17, "2");ArrayList<People> list = new ArrayList<>();Collections.addAll(list, p1, p2, p3);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));oos.writeObject(list);oos.close();ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));ArrayList<People> list1 = (ArrayList<People>) ois.readObject();ois.close();System.out.println(list1);}

        打印流

        打印流只有输出流,分为字节打印流PrintStream,字符打印流PrintWriter。

        字节打印流

        构造方法
                public PrintStream(OutputStream/File/String)            关联字节输出流/文件/文件路径
                public PrintStream(String fileName, Charset charset)    指定字符编码
                public PrintStream(OutputStreamout, boolean autoFlush)  自动刷新
                public PrintStream(OutputStream out, boolean autoFlush, String encoding)    指定字符编码且自动刷新
        成员方法:
                public void write(int b)            常规方法:规则跟之前一样,将指定的字节写出
                public void println(Xxx xx)         特有方法:打印任意数据,自动刷新,自动换行
                public void print(Xxx xx)           特有方法:打印任意数据,不换行
                public void printf(String format, Object... args)   特有方法:带有占位符的打印语句,不换行
        字节流底层没有缓冲区,开不开自动刷新都一样。

public static void main(String[] args) throws IOException {//1.创建字节打印流的对象PrintStream ps = new PrintStream(new FileOutputStream("a.txt"), true, Charset.forName("UTF-8"));//2.写出数据ps.println(97);//写出 + 自动刷新 + 自动换行ps.print(true);ps.println();ps.printf("%s%sdfsf","gsmlm","dd");//3.释放资源ps.close();}

        字符打印流

        字符打印流:
        构造方法
                public PrintWriter(Write/File/String)            关联字节输出流/文件/文件路径
                public PrintWriter(String fileName, Charset charset)    指定字符编码
                public PrintWriter(Write, boolean autoFlush)  自动刷新
                public PrintWriter(Write out, boolean autoFlush, String encoding)    指定字符编码且自动刷新
        成员方法:
                public void write(int b)            常规方法:规则跟之前一样,将指定的字节写出
                public void println(Xxx xx)         特有方法:打印任意数据,自动刷新,自动换行
                public void print(Xxx xx)           特有方法:打印任意数据,不换行
                public void printf(String format, Object... args)   特有方法:带有占位符的打印语句,不换行

        字符打印流自动刷新需要开启。

        true参数让 PrintWriter在每次调用 println(), printf()或 format()后自动刷新缓冲区,确保数据立即写入文件,这在需要实时持久化的场景(如日志记录)中非常有用。

public static void main(String[] args) throws IOException {//1.创建字符打印流的对象PrintWriter pw = new PrintWriter(new FileWriter("a.txt"),true);//2.写出数据pw.println("1");pw.print("2");pw.printf("%s%s34","5","6");//3.释放资源pw.close();}

        特殊的应用场景。

public static void main(String[] args) throws IOException {/**       打印流的应用场景* *///获取打印流的对象,此打印流在虚拟机启动的时候,由虚拟机创建,默认指向控制台//特殊的打印流,系统中的标准输出流,是不能关闭,在系统中是唯一的。PrintStream ps = System.out;//调用打印流中的方法println//写出数据,自动换行,自动刷新ps.println("1");ps.close();ps.println("2");System.out.println("3");}

        解压缩流 / 压缩流

        解压缩流ZipInputStream

        解压,把每一个ZipEntry类对象按照层级拷贝到本地的另一个文件夹中。

        getNextEntry()会依次返回文件夹所有的文件夹和文件,并返回其相对地址在Entry对象中。

        idea能.zip的压缩包。

public static void main(String[] args) throws IOException {//1.创建一个File表示要解压的压缩包File src = new File("D:\\a.zip");//2.创建一个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 entry;while((entry = zip.getNextEntry()) != null){System.out.println(entry);if(entry.isDirectory()){//文件夹:需要在目的地dest处创建一个同样的文件夹File file = new File(dest,entry.toString());file.mkdirs();}else{//文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)FileOutputStream fos = new FileOutputStream(new File(dest,entry.toString()));int b;while((b = zip.read()) != -1){//写到目的地fos.write(b);}fos.close();//表示在压缩包中的一个文件处理完毕了。zip.closeEntry();}}zip.close();}

        压缩流ZipOutputStream

        ZipEntry的路径是 ZIP 文件内部的相对虚拟路径对应需要压缩的文件。

        代码压缩一个txt重点在putNextEntry(),把ZipEntry对象放到压缩包当中也就是将输出流指向entry中的相对虚拟路径,每次放入的entry不同则输出流的指向路径也不同,这样便可以拷贝不同路径下的文件。

public static void main(String[] args) throws IOException {/**   压缩流*      需求:*          把D:\\a.txt打包成一个压缩包* *///1.创建File对象表示要压缩的文件File src = new File("D:\\a.txt");//2.创建File对象表示压缩包的位置File dest = new File("D:\\");//3.调用方法用来压缩toZip(src,dest);}/**   作用:压缩*   参数一:表示要压缩的文件*   参数二:表示压缩包的位置* */public static void toZip(File src,File dest) throws IOException {//1.创建压缩流关联压缩包ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));//2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹//参数:压缩包里面的路径ZipEntry entry = new ZipEntry("aaa\\bbb\\a.txt");//3.把ZipEntry对象放到压缩包当中,***也就是将输出流指向entry中的相对虚拟路径,// ***每次放入的entry不同则输出流的指向路径也不同,这样便可以拷贝不同的文件zos.putNextEntry(entry);//4.把src文件中的数据写到压缩包当中D:\aaa\bbb\a.txtFileInputStream fis = new FileInputStream(src);int b;while((b = fis.read()) != -1){zos.write(b);}zos.closeEntry();zos.close();}

        压缩一个文件夹。

        重点依旧在putNextEntry()。

public static void main(String[] args) throws IOException {/**   压缩流*      需求:*          把D:\\aaa文件夹压缩成一个压缩包* *///1.创建File对象表示要压缩的文件夹File src = new File("D:\\aaa");//2.创建File对象表示压缩包放在哪里(压缩包的父级路径)File destParent = src.getParentFile();//D:\\//3.创建File对象表示压缩包的路径 D:\\aaa.zipFile dest = new File(destParent,src.getName() + ".zip");//4.创建压缩流关联压缩包 压缩流目前指向 D:\\aaa.zipZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));//5.获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中//toZip(D:\aaa , D:\\aaa.zip, aaa);toZip(src,zos,src.getName());//aaa//6.释放资源zos.close();}/**   作用:获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中*   参数一:数据源*   参数二:压缩流*   参数三:压缩包内部的路径* */public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {//toZip(D:\aaa  ,        D:\\aaa.zip,        aaa);//1.进入src文件夹File[] files = src.listFiles();//2.遍历数组for (File file : files) {if(file.isFile()){//3.判断-文件,变成ZipEntry对象,放入到压缩包当中ZipEntry entry = new ZipEntry(name + "\\" + file.getName());//aaa\\no1\\a.txtzos.putNextEntry(entry);//读取文件中的数据,写到压缩包FileInputStream fis = new FileInputStream(file);int b;while((b = fis.read()) != -1){zos.write(b);}fis.close();zos.closeEntry();}else{//4.判断-文件夹,递归toZip(file,zos,name + "\\" + file.getName());//     no1            aaa   \\   no1}}}

        Commons-io工具包

         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, CharSequence 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)          写出数据

public static void main(String[] args) throws IOException {File src = new File("a.txt");File dest = new File("copy.txt");FileUtils.copyFile(src,dest);File src1 = new File("D:\\aaa");File dest1 = new File("D:\\bbb");FileUtils.copyDirectoryToDirectory(src1,dest1);File src2 = new File("D:\\bbb");FileUtils.cleanDirectory(src2);}

        Hutool

        FileUtil类:
                file:根据参数创建一个file对象
                touch:根据参数创建文件

                writeLines:把集合中的数据写出到文件中,覆盖模式。
                appendLines:把集合中的数据写出到文件中,续写模式。
                readLines:指定字符编码,把文件中的数据,读到集合中。
                readUtf8Lines:按照UTF-8的形式,把文件中的数据,读到集合中

                copy:拷贝文件或者文件夹

public static void main(String[] args) throws IOException {File file1 = FileUtil.file("D:\\", "aaa", "a", "a.txt");System.out.println(file1);//D:\aaa\a\a.txt//touch 会自动创建父路径上的文件File touch = FileUtil.touch(file1);System.out.println(touch);ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("aaa");list.add("aaa");File file2 = FileUtil.writeLines(list, "D:\\a.txt", "UTF-8",true);System.out.println(file2);List<String> list1 = FileUtil.readLines("D:\\a.txt", "UTF-8");System.out.println(list1);}

http://www.dtcms.com/a/352889.html

相关文章:

  • npm run start 的整个过程
  • LeetCode 刷题【54. 螺旋矩阵】
  • 共享云服务器替代传统电脑做三维设计会卡顿吗
  • Spring Boot 启动失败:循环依赖排查到懒加载配置的坑
  • 手写MyBatis第37弹: 深入MyBatis MapperProxy:揭秘SQL命令类型与动态方法调用的完美适配
  • 特征降维-特征组合
  • YOLO 目标检测:数据集构建(LabelImg 实操)、评估指标(mAP/IOU)、 NMS 后处理
  • Java全栈开发工程师的面试实战:从基础到微服务
  • 科普 | 5G支持的WWC架构是个啥(2)?
  • Android系统框架知识系列(十七):Telephony Service - 移动通信核心引擎深度解析
  • 5G NR学习笔记 预编码(precoding)和波束赋形(beamforming)
  • DAY 58 经典时序预测模型2
  • 不用伪基站也能攻破5G?Sni5Gect框架如何实现“隐形攻击”
  • spire.doc在word中生成公式
  • OpenCV实战1.信用卡数字识别
  • 第1.7节:机器学习 vs 深度学习 vs 强化学习
  • 20.19 LoRA微调Whisper终极指南:3步实现中文语音识别错误率直降37.8%
  • Apifox 8 月更新|新增测试用例、支持自定义请求示例代码、提升导入/导出 OpenAPI/Swagger 数据的兼容性
  • TDengine与StarRocks在技术架构和适用场景上有哪些主要区别?
  • 【C++】set 容器的使用
  • 面试记录6 c++开发工程师
  • 【PostgreSQL内核学习:通过 ExprState 提升哈希聚合与子计划执行效率】
  • 前端漏洞(下)- URL跳转漏洞
  • buuctf——web刷题第四页
  • Ansible模块实战,操作技巧
  • 局部厚铜:PCB技术革新,构筑电气新时代的动力基石
  • AGDO-BP+NSGAII梯度下降优化算法优化BP神经网络+NSGAII多目标优化算法,三目标和四目标案例
  • Spring Start Here 读书笔记:附录A. Architectural approaches
  • Linux系统深度优化指南:CPU、I/O与内核参数调优实战
  • C++:对拍(教程超详细)