Java 文件

Java IO教程 - Java文件


java.nio.file.Files 包含所有允许我们对Path对象执行大多数文件操作的静态方法。

创建新文件

文件可以创建常规文件,目录,符号链接和临时文件/目录。

大多数方法接受FileAttribute类型的varargs参数,这允许我们指定文件属性。

createFile()方法创建一个新的常规文件。创建的新文件为空。

如果文件已存在,或父目录不存在,文件创建将失败。

以下代码显示如何创建新文件。

import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {
  public static void main(String[] args) {
    Path p1 = Paths.get("test.txt");
    try {
      Files.createFile(p1);
      System.out.format("File created:  %s%n", p1.toRealPath());
    } catch (FileAlreadyExistsException e) {
      System.out.format("File %s  already exists.%n", p1.normalize());
    } catch (NoSuchFileException e) {
      System.out.format("Directory %s  does  not  exists.%n", p1.normalize()
          .getParent());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

上面的代码生成以下结果。


创建目录

createDirectory()和createDirectories()方法创建一个新目录。

如果父目录不存在,createDirectory()方法将失败。

createDirectories()方法创建不存在的父目录。

createTempDirectory()和createTempFile()方法分别创建一个临时目录和一个临时文件。

以下代码显示了如何创建临时文件和目录。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {
  public static void main(String[] args) throws Exception {
      String dirPrefix = "KDir";
      Path tDir = Files.createTempDirectory(dirPrefix);
      System.out.println("Temp directory: " + tDir);
      String fPrefix = "Header_";
      String fSuffix = ".txt";
      Path tFile1 = Files.createTempFile(fPrefix, fSuffix);
      System.out.println("Temp file1: " + tFile1);

      Path p1 = Paths.get("C:\\temp");
      Path tFile2 = Files.createTempFile(p1, fPrefix, fSuffix);
      System.out.println("Temp file2: " + tFile2);
  }
}

不会自动删除临时文件/目录。我们可能希望使用java.io.File类的deleteOnExit()方法在JVM退出时删除该文件。

Path  tempFile = Files.createTempFile("myTempFile", ".txt");
tempFile.toFile().deleteOnExit();

上面的代码生成以下结果。


删除文件

从文件中删除(Path p)和deleteIfExists(Path p)以删除文件,目录和符号链接。

如果删除失败,delete()方法将抛出异常。

如果要删除的文件不存在,deleteIfExists()方法不会抛出NoSuchFileException异常。

如果它删除文件,则返回true。否则,它返回false。

以下代码显示如何删除文件和处理异常:

import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {
  public static void main(String[] args) throws Exception {
    Path p = Paths.get("C:\\Java_Dev\\test1.txt");

    try {
      Files.delete(p);
      System.out.println(p + "  deleted successfully.");
    } catch (NoSuchFileException e) {
      System.out.println(p + "  does  not  exist.");
    } catch (DirectoryNotEmptyException e) {
      System.out.println("Directory " + p + "  is not  empty.");
    } catch (IOException e) {
      e.printStackTrace();
    }

  }
}

上面的代码生成以下结果。

存在文件

文件类有两个方法,分别是exists(Path p,LinkOption ... options)和notExists(Path p,LinkOption ... options)来检查文件的存在和不存在。

复制文件

文件类复制(Path source,Path target,CopyOption ... options)方法可以将指定的源路径复制到指定的目标路径。

如果指定的源文件是符号链接,则将复制符号链接的目标,而不是符号链接。

如果指定的源文件是目录,则创建目标位置处的空目录,而不复制目录的内容。

我们可以使用copy()方法指定一个或多个以下复制选项:

  • StandardCopyOption.REPLACE_EXISTING
  • StandardCopyOption.COPY_ATTRIBUTES
  • LinkOption.NOFOLLOW_LINKS

我们可以指定REPLACE_EXISTING选项来替换现有的目标文件。

如果目标文件是符号链接,并且如果存在,则通过指定REPLACE_EXISTING选项而不是符号链接的目标来替换符号链接。

COPY_ATTRIBUTES选项将源文件的属性复制到目标文件。

如果使用NOFOLLOW_LINKS选项,则copy()方法复制符号链接,而不是符号链接的目标。

以下代码显示了使用copy()方法复制文件。如果复制操作失败,它会处理可能的异常。

import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.DirectoryNotEmptyException;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;

public class Main {
  public static void main(String[] args) {
    Path source = Paths.get("C:\\Java_Dev\\test1.txt");
    Path target = Paths.get("C:\\Java_Dev\\test1_backup.txt");

    try {
      Path p = Files.copy(source, target, REPLACE_EXISTING, COPY_ATTRIBUTES);
      System.out.println(source + "  has  been  copied to " + p);
    } catch (FileAlreadyExistsException e) {
      System.out.println(target + "  already exists.");
    } catch (DirectoryNotEmptyException e) {
      System.out.println(target + "  is not  empty.");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

移动文件

Files类的move(Path source,Path target,CopyOption ... options)方法移动或重命名文件。

如果指定的目标文件已存在,则移动操作将失败。

我们可以指定REPLACE_EXISTING选项来替换现有的目标文件。

如果要移动的文件是符号链接,它将移动符号链接,而不是符号链接的目标。

move()方法只能用于移动一个空目录。

除了REPLACE_EXISTING复制选项,我们可以使用ATOMIC_MOVE作为另一个CopyOption。

如果使用ATOMIC_MOVE选项,如果无法以原子方式移动文件,则会抛出AtomicMoveNotSupportedException。

如果指定ATOMIC_MOVE选项,则忽略所有其他选项。

以下代码显示了如何通过处理可能的异常来移动文件:

import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;

import java.io.IOException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {
  public static void main(String[] args) throws Exception {
    Path source = Paths.get("C:\\Java_Dev\\test1.txt");
    Path target = Paths.get("C:\\Java_Dev\\dir2\\test1.txt");

    try {
      Path p = Files.move(source, target, ATOMIC_MOVE);
      System.out.println(source + "  has  been  moved to " + p);
    }catch (NoSuchFileException e) {
      System.out.println("Source/target does  not  exist.");
    } catch (FileAlreadyExistsException e) {
      System.out.println(target + "  already exists.  Move failed.");
    } catch (DirectoryNotEmptyException e) {
      System.out.println(target + "  is not  empty.  Move failed.");
    } catch (AtomicMoveNotSupportedException e) {
      System.out.println("Atomic move is not  supported. MOve  failed.");
    } catch (IOException e) {
      e.printStackTrace();
    }

  }
}

上面的代码生成以下结果。