Files类专门的静态方法用来操作文件、目录等。通过Files,我们可以删除、创建、复制、移动文件,能够创建针对文件的InputStream、OutputStream、BufferedReader、BufferedWriter、channel等。

创建InputStream、BufferedReader、Channel

  1. public static void main(String[] args) throws IOException {
  2. Path path = Paths.get("/Users", "cuihualong", "Desktop", "monitor.sql");
  3. InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ);
  4. BufferedReader bufferedReader = Files.newBufferedReader(path);
  5. SeekableByteChannel seekableByteChannel = Files.newByteChannel(path, StandardOpenOption.READ);
  6. }

创建OutputStream、BufferedWriter与InputStream、BufferedReader基本类似,这里就不罗列了。

读取文件

Files提供了三个方法用于读取整个文件,可以读取为字节数组和String列表:
image.png

读取整个文件到字节数组

第一个方法readAllBytes用来读取整个文件的内容到一个字节数组。想想一下之前我们要想使用InputStream来读取整个文件到一个字节数组,需要循环读取,现在有了这个方法就简单多了,它的实现如下:

  1. public static byte[] readAllBytes(Path path) throws IOException {
  2. try (SeekableByteChannel sbc = Files.newByteChannel(path);
  3. InputStream in = Channels.newInputStream(sbc)) {
  4. long size = sbc.size();
  5. if (size > (long)MAX_BUFFER_SIZE)
  6. throw new OutOfMemoryError("Required array size too large");
  7. return read(in, (int)size);
  8. }
  9. }

它首先获取了channel,然后通过Channels工具类将Channel映射为流,然后通过流来读取。

读取整个文件到List

  1. public static List<String> readAllLines(Path path, Charset cs) throws IOException {
  2. try (BufferedReader reader = newBufferedReader(path, cs)) {
  3. List<String> result = new ArrayList<>();
  4. for (;;) {
  5. String line = reader.readLine();
  6. if (line == null)
  7. break;
  8. result.add(line);
  9. }
  10. return result;
  11. }
  12. }

这个方法接收一个Path和一个字符集,它是通过BufferedReader来实现的。方式就是在循环中取调用BufferedReader的readLine方法。

写入文件

对于写入文件,Files同样提供了三个方法:
image.png
我们来重点看第一个:

  1. public static Path write(Path path, byte[] bytes, OpenOption... options)
  2. throws IOException
  3. {
  4. // ensure bytes is not null before opening file
  5. Objects.requireNonNull(bytes);
  6. try (OutputStream out = Files.newOutputStream(path, options)) {
  7. int len = bytes.length;
  8. int rem = len;
  9. while (rem > 0) {
  10. int n = Math.min(rem, BUFFER_SIZE);
  11. out.write(bytes, (len-rem), n);
  12. rem -= n;
  13. }
  14. }
  15. return path;
  16. }

它是通过OutputStream来实现的。

复制、删除、移动文件

copy方法可以复制文件,它接收三个参数,前两个都是Path,表示源文件Path和目标文件Path,第三个是复制的选项。

  1. public static Path copy(Path source, Path target, CopyOption... options)
  2. throws IOException
  3. {
  4. FileSystemProvider provider = provider(source);
  5. if (provider(target) == provider) {
  6. // same provider
  7. provider.copy(source, target, options);
  8. } else {
  9. // different providers
  10. CopyMoveHelper.copyToForeignTarget(source, target, options);
  11. }
  12. return target;
  13. }


move方法用来移动文件,它和copy一样,也接收三个参数,并且含义一致。

  1. public static Path move(Path source, Path target, CopyOption... options)
  2. throws IOException
  3. {
  4. FileSystemProvider provider = provider(source);
  5. if (provider(target) == provider) {
  6. // same provider
  7. provider.move(source, target, options);
  8. } else {
  9. // different providers
  10. CopyMoveHelper.moveToForeignTarget(source, target, options);
  11. }
  12. return target;
  13. }

delete方法用来删除文件,它只需要一个参数,即代表文件的Path。

  1. public static void delete(Path path) throws IOException {
  2. provider(path).delete(path);
  3. }

除了上面这些方法,files还有很多其他实用的方法,这里我就不多介绍了。