My Blog

Apache_common_io

记录 Apache common io 包中常用的 IO 流、文件流方法

学习笔记,仅供参考

参考B站Mirco_Frank - java 进阶 | Apache common io official site | Reference API doc


Apache common io

apache 开发的用于 io 操作的工具包,提供了多种方法来操作不同类型的流、文件等。Maven 库下载 commons-io/2.7


🧪 IOUtils Class

常用的 IO 流的操作在 IOUtils 类中,该类的方法都是静态的,所以可以直接用类名调用,而且读数据的方法内部都有 4K buffer 缓存区,直接用就好,也不用 new BufferedInputStream 了。

下面列举一些常用的方法,参考自这里

IOUtils.buffer()

根据所给的流(InputStream, OutputStream, Reader, Writer)给它们创建一个缓冲流 (BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter)

// 1. inputStream -> bufferedInputStream
BufferedInputStream in = IOUtils.buffer(new FileInputStream("xx/input.txt"));

// print content by using IOUtils.toString(InputStream, charsetEncoding)
System.out.println(IOUtils.toString(in, Standardcharsets.UTF_8));

// 2. Reader -> bufferedReader
BufferedRader in = IOUtils.buffer(new FileReader("xx/input.txt"));

/*---------------------------------------------*/

// 3. OutputStream -> BufferedOutputStream
BufferedOutputStream out = IOUtils.buffer(new FileOutputStream("xx/output.txt"));

// 4. Writer -> BufferedWriter
BufferedWriter out = IOUtils.buffer(new FileWriter("xx/output.txt"));

IOUtils.read()

IOUtils.read(InputStream, byte[])   // 从所给的输入流中读取数据,并将读到的数据暂存在 byte[] 数组中,返回所读到的字节数

// 假设 xx/input.txt 内容为 "Hello-World"
InputStream in = new FileInputSteram("xx/input.txt");
byte[] bytes = new byte[7];
int numberOfBytesRead = IOUtils.read(in, bytes);  // read data to byte array
System.out.println(numberOfBytesRead); // print return value : 7
System.out.println(new String(bytes));  // byte[] -> String and print result : "Hello-W"

IOUtils.read(Reader, char[])   // 类似的,将字符输入流中读到的数据存放在 char[] 数组中,并返回读到的字符数

// 假设 xx/input.txt 内容为 "Hello-World"
Reader in = new FileReader("xx/input.txt");
char[] chars = new char[7];
int numberOfCharsRead = IOUtils.read(in, chars);  // read data to char array
System.out.println(numberOfCharsRead); // print return value : 7
System.out.println(new String(chars));  // char[] -> String and print result : "Hello-W"

重载方法 IOUtils.read(Inputstream, bytes, offset, length) ,指从输入流中读取数据到 byte 数组中,其中 offset 指从 byte 的那个下标开始存放数据,length 为要存放的数据长度(字节数)。对 Reader 也是类似的


IOUtils.readFully()

IOUtils.readFully(InputStream, byte[])   // 与 read 类似,它试图读取数据来填满 byte 数组,若是填不满(即数组长度大于文件的内容),就会抛出 EOFException,返回为 void

这里就不再演示了,重载方法也是 IOUtils.readFully(Inputstream, bytes, offset, length)


IOUtils.readLines()

IOUtils.readLines(InputStream in, String charsetName)   // 从输入流中读取数据并指定所用的字符集,将读到的数据以 List<String> 的形式返回

InputStream in = new FileInputSteram("xx/input.txt");
List<String> lists = IOUtils.readLines(in, "UTF-8");  // read data to list of string
System.out.println(lists); // print lists

Reader 同理


IOUtils.write()

IOUtils.write(String, OutputStream, CharsetName)   // 将 String 类型的数据写入输出流中,并指定字符集,除了 String 外还有 char[], byte[] 等其他的类型

OutputStream out = IOUtils.buffer(new FileOutputStream("xx/output.txt"));

IOUtils.write("data1", out, StandardCharsets.UTF_8);  // write "data1" string to outputstream and specify utf8 charset 
IOUtils.write(System.lineSeparator(), out, StandardCharsets.UTF_8); // 写入系统的换行符到文件
IOUtils.write("data2", out, StandardCharsets.UTF_8);  // write "data2" string

out.close(); // close stream

字符流 Writer 同理


IOUtils.copy()

copy(InputStream in, OutputStream out)   // 从输入流复制数据到输出流,返回所复制的字节数(最大为 2GB),超过 2GB 则返回 -1,所以 2GB 以上的可用 copyLarge() 用法与 copy() 类似,但它返回的是 long 型。另外,该方法内部也是有缓存数组,所以不用传缓冲文件流

    public void test() {
        InputStream in = new FileInputStream("file/sample.txt");
        OutputStream out = new FileOutputStream("file/sample-copy.txt");
        // copying
        int numberOfBytesCopy = IOUtils.copy(in, out);
        System.out.println(numberOfBytesCopy);

        out.close();
        in.close();
    }

字符流 Writer 同理


还有一些方法下面就简单摘录了,以 InputStream 为例,Reader 也是类似的

  • IOUtils.skip(InputStream in, long toSkip)   // 跳过输入流的 toSkip 个字节后,在进行操作,返回所跳过的字节数

  • IOUtils.contentEquals(InputStream in1, InputStream in2)   // 判断两输入流的内容是否相同,相同返回 true,不同返回 false

  • IOUtils.contentEqualsIgnoreEOL(InputStream in1, InputStream in2)   // 判断两输入流的内容是否相同且忽略空行,相同返回 true,不同返回 false

  • IOUtils.toString(InputStream input, Charset charset)   // 以字符串的形式获取输入流的内容,并指定字符集;还有其他类似的方法:IOUtils.toByteArray()、IOUtils.toCharArray() 等


📂 FileUtils Class

常用的文件操作工具类,同样所有的方法都是 static,功能有写文件、读文件、复制文件和新建文件夹等。下面就一一道来

ReadFile

  • FileUtils.readLines(File file, Charset charset)   // 以指定字符集的形式读取所给文件的内容,并且以 list<string> 的形式返回,list 中每个元素代表文件中的一行内容

    public void fileUtilsRead() throws IOException {
        File file = new File("D:\\DevTools\\demo\\file\\sample.txt");
        // read data from specify file
        List<String> list = FileUtils.readLines(file, StandardCharsets.UTF_8);
        System.out.println(list);
    }
  • FileUtils.readFileToString(File file, Charset charset)   // 以字符串的形式读取整个文件的内容,返回的是字符串;当然还可用 FileUtils.readFileToByteArray(file) 返回 byte 数组


WriteFile

  • FileUtils.write(File file, CharSequence data, Charset charset)   // 将数据写入到所给的文件中,若文件不存在,则新建该文件及文件路径

    public void fileUtilsWrite() throws IOException {
        File file = new File("D:\\DevTools\\demo\\file\\fileUtilsWrite.txt");
        String data = "some-data";
        // write data to given file
        FileUtils.write(file, data, StandardCharsets.UTF_8);
    }

还可以用其重载方法来追加数据,而放在文件的数据被覆盖。FileUtils.write(File file, CharSequence data, Charset charset, boolean append) , append 为 true 就表示追加数据

  • FileUtils.writeLines(File file, Collection<?> lines)   // 将集合每个元素 toString() 的值写进文件中,一个元素占一行

    public void fileUtilsWrite() throws IOException {
        File file = new File("D:\\DevTools\\demo\\file\\fileUtilsWrite.txt");
        List<String> list = new ArrayList<>();
        list.add("line1");
        list.add("line2");
        list.add("line3");
        FileUtils.writeLines(file, list);
    }
    
    /**
    *  写入文件的内容如下:
    *  line1
    *  line2
    *  line3
    */

同样,它也有好多重载方法以供不同的需求

FileUtils.writeLines(File file, Collection<?> lines, boolean append) // 是否追加内容

FileUtils.writeLines(File file, Collection<?> lines, String lineEnding, boolean append) // 用所给的 lineEnding 来分隔每个元素,如 lineEnding 为“-”,那么上面的结果就变为

/**
 *  带有分隔符写入:
 *  line1-line2-line3
 */

FileUtils.writeLines(File file, String charsetName, Collection<?> lines, String lineEnding, boolean append) // 指定字符集

  • FileUtils.writeStringToFile(File file, String data, Charset charset)   // 将字符串写入所给的文件中,重载方法多了是否追加

  • FileUtils.writeByteArrayToFile(File file, byte[] data)   // 将字节数组写入到文件中,重载方法多了是否追加、 offset and length,操作不当会造成 IndexOutOfBoundsException


CopyFile

  • FileUtils.copyFile(File srcFile, File destFile)   // 将源文件的内容复制到目标文件中,若目标文件不存在,则新建该文件及文件路径;若目标文件存在,则覆盖其内容

    public void fileUtilsCopy() throws IOException {
        File srcFile = new File("D:\\DevTools\\demo\\file\\sample.txt");
        File destFile = new File("D:\\DevTools\\demo\\file\\sampleCopy.txt");
        // copy srcfile to destfile
        FileUtils.copyFile(srcFile, destFile);
    }

重载方法 FileUtils.copyFile(File srcFile, File destFile, boolean preserveFileDate) 中的 preserveFileDate 指是否要将源文件的修改日期也保留到目标文件中

FileUtils.copyFile(File srcFile, FileOutputStream out) 将文件输出流作为复制的目标

当用 FileUtils.copyFile() 时,若源文件或目标文件所给的路径是文件夹时,则会抛出 IOException 异常

  • FileUtils.copyDirectory(File srcDir, File destDir)   // 复制源文件夹及所有文件到目标文件夹,同理,存在则覆盖,不存在则新建

  • FileUtils.copyFileToDirectory(File srcFile, File destDir)   // 复制源文件到目标文件夹中

  • FileUtils.copyInputStreamToFile(InputStream in, File destFile)   // 复制输入流到目标文件中


MoveFile

  • FileUtils.moveFile(File srcFile, File destFile)   // 将源文件移到目标文件中

  • FileUtils.moveFileToDirectory(File srcFile, File destDir, boolean createDestDir)   // 若是创建文件夹失败,且目标文件夹不存在就会抛出 FileNotFoundException;若是目标文件夹中有与源文件同名的,则抛出 apache.common.io.FileExistsException


DeleteFile

  • FileUtils.deleteQuietly(File file)   // 删除文件且不抛出异常,删除成功返回 true,失败则 false

  • FileUtils.forceDelete(File file)   // 删除文件,当文件不存在时,抛出 FileNotFoundException

  • FileUtils.forceDeleteOnExit(File file)   // 当 JVM 退出时,删除所给的对象,若给的时文件夹,则会删除它及其文件;可以用来删除临时文件或缓存文件