Java--Files

Fiels

Files类可以使得普通文件操作变得快捷。

例如,可以用下面的方式很容易地读取文件的所有内容:

byte[] bytes = Files.readAllBytes(path);

如果像将文件当做字符串读入,那么可以在调用readAllBytes之后执行下面的代码:

String content = new String(bytes, charset);

但是如果希望将文件当做行序列读入,那么可以调用:
``java
List lines = Files.readAllLines(path, charset);


相反地,如果希望写出一个字符串到文件中,可以调用:
```java
Files.write(path, content.getBytes(charset));

向指定文件追加内容,可以调用:

Files.write(path, content,getBytes(charset), StandardOpenOption.APPEND);

还可以用下面的语句将一个行的集合写出到文件中:

Files.write(path, lines);

这些简便方法适用于处理中等长度的文本文件,如果要处理的文件长度比较大,或者是二进制文件,那么还是应该使用所熟知的输入/输出流或者读入器/写出器:

			InputStream in = Files.newInputStream(path);
            OutputStream out = Files.newOutputStream(path);
            BufferedReader reader = Files.newBufferedReader(path);
            BufferedWriter writer = Files.newBufferedWriter(path);

java.nio.file.Files 7

  • static byte[] readAllBytes(Path path)

  • static List<String> readAllLines(Path path, Charset charset)
    读入文件的内容

  • static Path write(Path path, byte[] contents, OpenOption... options)

  • static Path write(Path path, Iterabble<? extends CharSwquence> contents, OpenOption options)
    将给定内容写出到文件中,并返回path

  • static InputStream newInputStream(Path path, OpenOption... options)

  • static OutputStream newOutputStream(Path path, OpenOption... options)

  • static BufferedReader newBufferedReader(Path path, Charset cs)

  • static BufferedWriter newBufferedWriter(Path path, Charset cs, OpenOption... options)
    打开一个文件,用于读入或写出

创建文件和目录

创建新目录可以调用:

Files.createDirectory(path);

其中,路径中除最后一个部件外,其他部分都必须是已存在的。要创建路径中的中间目录,应该使用:

Files.createDirectories(path);

可以使用下面的语句创建一个空文件:

Files.createFile(path);

如果文件已经存在了,那么这个调用就会抛出异常。检查文件是否存在和创建文件是原子性的,如果文件不存在,该文件就会被创建,并且其它程序在此过程中无法执行文件创建操作的。

有些便捷方法可以用来在给定位置或者系统指定位置创建临时文件或临时目录:

Path newPath = Files.createTempFile(dir, prefix, suffix);
Path newPath = Files.createTempFile(prefix, suffix);
Path newPath = Files.createTempFile(dir, prefix);
Path newPath = Files.createTempFile(prefix);

其中dir是一个Path对象,prefix和suffix是可以为null的字符串。例如,调用Files.createTempFile(null, ".txt");可能会返回一个像/tmp/1233423543546.txt这样的路径。

java.nio.file.Files 7

  • static Path createFile(Path path, FileAttribute<?>... attrs)
  • static Path createDirectory(Path dir, FileAttribute<?>... attrs)
  • static Path createDirectories(Path dir, FileAttribute<?>... attrs)
    创建一个文件或目录,createDirectories方法还会创建路径中所有的中间目录

复制、移动和删除文件

将文件从一个位置复制到另一个位置可以直接调用:

Files.copy(fromPath,toPath);

移动文件(即复制并删除原文件)可以调用

Files.move(fromPath, toPath);

如果目标路径已经存在,那么复制或移动将失败。如果想要覆盖已有的目标路径,可以使用REPLACE_EXISTING选项。如果想要复制所有的文件属性,可以使用COPY_ATTRIBUTES选项。也可以像下面这样同时选择这两个选项:

Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING,StandardCopyOption.COPY_ATTRIBUTES);

你可以将移动操作定义为原子性的,这样就可以保证要么移动操作成功完成,要么源文件继续保持在原来位置。具体可以使用ATOMIC_MOVE选项来实现:

Files.copy(fromPath, toPath, StandardCopyOption.ATOMIC_MOVE);

你还可以将一个输入流复制到Path中,这表示你想要将该输入流存储到硬盘上。类似地,你可以将一个Path复制到输出流中。可以使用使用下面的调用:

Files.copy(inputStream, toPath);
Files.copy(fromPath, outputStream);

至于其它对copy的调用,可以根据需要提供相应的复制选项。最后删除文件可以调用:

Files.delete(path);

如果要删除的文件不存在,这个方法就会抛出异常。因此,可转而使用下面的方法:

boolean deleted = Files.deleteIfExists(path);

该删除方法还可以用来移出空目录。

获取文件信息

下面的静态方法都将返回一个boolean值,表示监察路径的某个属性的结果:

  • exists
  • isHidden
  • isReadable, isWritable, isExecutable
  • isRegularFile, isDirectory, isSymbolicLink

size()方法将返回文件的字节数:

long fileSize = Files.size(path);

getOwner方法将文件的拥有者作为java.nio.file.attribute.UserPrincipal的一个实例返回。

所有的文件系统都会报告一个基本属性集,它们被封装在BasicFileAttributes接口中,这些属性与上述信息有部分重叠。基本文件属性包括:

  • 创建文件、最后一次访问以及最后一次修改文件的时间,这些时间都表示成java.nio.file.attribute.FileTime
  • 文件是常规文件、目录还是符号链接,抑或这三者都不是
  • 文件尺寸
  • 文件主题,这是某种类的对象,具体所属类与文件系统相关,有可能是文件的唯一标识符,也可能不是

java.nio.file.Files 7

  • static boolean exists(Path path)

  • static boolean isHidden(Path path)

  • static boolean isReadable(Path path)

  • static boolean isWritable(Path path)

  • static boolean isExecutable(Path path)

  • static boolean isRegularFile(Path path)

  • static boolean isDirectory(Path path)

  • static boolean isSymbolicLink(Path path)
    检查由路径指定的文件的给定属性

  • static long size(Path path)
    获取文件按字节数度量的尺寸

  • A readAttributes(Path path, Class<A> type, LinkOption... options)
    读取类型为A的文件属性

java.nio.file.attribute.BasicFileAttributes

  • FileTime createionTime()
  • FileTime lastAccessTime()
  • FileTime lastModifiedTime()
  • boolean isRegularFile()
  • boolean isDirectory()
  • boolean isSymbolicLink()
  • long size()
  • object fileKey()
    获取所请求的属性

访问目录中的项

静态的Files.list方法会返回一个可以读取目录中各个项的Stream<Path>对象。目录是被惰性读取的,这使得处理具有大量项的目录可以变得更高效。

因为读取目录涉及需要关闭的系统资源,所以应该使用try块:

		try {
            Files.list(Paths.get("lambdaModule", "src", "pers", "zhang"))
                    .forEach(f -> System.out.println(f));
        } catch (IOException e) {
            e.printStackTrace();
        }

list方法不会进入子目录。为了处理目录中所有子目录,需要使用File.walk方法(广度优先搜索)。

		try {
            Files.walk(Paths.get("lambdaModule", "src", "pers", "zhang"))
                    .forEach(f -> System.out.println(f));
        } catch (IOException e) {
            e.printStackTrace();
        }

可以通过调用File.walk(pathRoRoot, depth)来限制想要访问的树的深度。两种walk方法都具有FileVisitOption…的可边长参数,但是你只能提供一种选项:FOLLOW_LINKS,即跟踪符号链接。

这段代码使用了Files.walk方法来讲一个目录复制到另一个目录:

		Path source = Paths.get("/Users/acton_zhang/Note/test/1");
        Path target = Paths.get("/Users/acton_zhang/Note/test/2");
        Files.walk(source).forEach(p -> {
            try {
                Path q = target.resolve(source.relativize(p));
                if (Files.isDirectory(p))
                    Files.createDirectories(q);
                else
                    Files.copy(p, q);
            }catch (IOException e) {
                e.printStackTrace();
            }

        });

遗憾的是,你无法很容易地使用Files.walk方法来删除目录树,因为你需要在删除父目录之前必须先删除子目录。

发布了892 篇原创文章 · 获赞 2314 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/105135556