`

Java7中那些新特性 - 4 (文件操作篇)

阅读更多
  以前两篇博客都是关于文件路径和文件信息,今天我们来看看Java7中提供了哪些新的API,可以让我们非常简单的复制、移动和删除文件以及路径。

  首先来说如何创建一个新的文件夹和文件,直接上例子。

    public static void main(String[] args) {

        try {

            Path directoryPath = Paths.get("D:/home/sample");
            Files.createDirectory(directoryPath);
            System.out.println("Directory created successfully!");

            Path filePath = Paths.get("D:/home/sample/test.txt");
            Files.createFile(filePath);
            System.out.println("File created successfully!");

            Path directoriesPath = Paths.get("D:/home/sample/subtest/subsubtest");
            System.out.println("Sub-directory created successfully!");
            Files.createDirectories(directoriesPath);

        } catch (FileAlreadyExistsException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  上例中,在调用createFile方法时,如果想要创建的文件已经存在,FileAlreadyExistsException会被抛出。createFile和createDirectory这个两个方法都是原子性的,即要不整个操作都能成功或者整个操作都失败。

  复制一个文件同样非常简单,Files的copy方法就可以实现。在复制文件时,我们可以对复制操作加一个参数来指明具体如何进行复制。java.lang.enum.StandardCopyOption这个枚举可以用作参数传递给copy方法。

ATOMIC_MOVE 原子性的复制
COPY_ATTRIBUTES 将源文件的文件属性信息复制到目标文件中
REPLACE_EXISTING 替换已存在的文件


    public static void main(String[] args) {

        Path newFile = Paths.get("D:/home/sample/newFile.txt");
        Path copiedFile = Paths.get("D:/home/sample/copiedFile.txt");

        try {

            Files.createFile(newFile);
            System.out.println("File created successfully!");

            Files.copy(newFile, copiedFile, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("File copied successfully!");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


  此外copy方法还支持输入输出流作为参数,以来复制非文件系统的信息。而复制文件夹的操作也并不复杂,如下例。

    public static void main(String[] args) {

        Path originalDirectory = Paths.get("D:/home/sample");
        Path newDirectory = Paths.get("D:/home/sample/tmp");

        try {

            Files.copy(originalDirectory, newDirectory);
            System.out.println("Directory copied successfully!");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {

        Path newFile = Paths.get("D:/home/sample/java7WebSite.html");
        URI url = URI.create("http://jdk7.java.net/");

        try (InputStream inputStream = url.toURL().openStream()) {

            Files.copy(inputStream, newFile);
            System.out.println("Site copied successfully!");
            
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


  在我们做开发工作的时候,有时需要用到一个临时文件做介质,这些临时文件不需要被持久的保存下来,当程序结束或者一个方法处理完,就可以被删除掉了。Java7中提供了对临时文件良好的操作方法。

      public static void main(String[] args) {

        try {

            Path rootDirectory = Paths.get("D:/home/sample");
            Path tempDirectory = Files.createTempDirectory(rootDirectory, "");

            System.out.println("Temporary directory created successfully!");
            String dirPath = tempDirectory.toString();
            System.out.println(dirPath);

            Path tempFile = Files.createTempFile(tempDirectory, "", "");

            System.out.println("Temporary file created successfully!");
            String filePath = tempFile.toString();
            System.out.println(filePath);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


  我们可以通过给createTempDirectory和createTempFile方法传递不同的参数来指定临时文件的前缀和后缀,具体使用方式请参照JDK文档。

  Files类还提供了一些方法,方便我们修改那些文件本身和时间相关的属性。

      public static void main(String[] args) {

        try {

            Path path = Paths.get("D:/home/projects/note.txt");

            BasicFileAttributeView view = Files.getFileAttributeView(path, BasicFileAttributeView.class);

            FileTime lastModifiedTime;
            FileTime lastAccessTime;
            FileTime createTime;

            BasicFileAttributes attributes = view.readAttributes();

            lastModifiedTime = attributes.lastModifiedTime();
            createTime = attributes.creationTime();

            long currentTime = Calendar.getInstance().getTimeInMillis();
            lastAccessTime = FileTime.fromMillis(currentTime);

            view.setTimes(lastModifiedTime, lastAccessTime, createTime);            
            System.out.println(attributes.lastAccessTime());
            
            Files.setLastModifiedTime(path, lastModifiedTime);            
            System.out.println(Files.getLastModifiedTime(path));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


  当要修改文件所属用户的时候,运行Java程序的用户需要有特定的权限,这里对不同操作系统的权限控制方式不做介绍,大家可以自己学习一下。下例中的用户JavaUser必须是存在在系统中的,否则会抛UserPrincipalNotFoundException异常。

    public static void main(String[] args) {
        
        try {
            
            Path path = Paths.get("D:/home/projects/note.txt");
            
            UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
            UserPrincipal userPrincipal = lookupService.lookupPrincipalByName("JavaUser");
            
            Files.setOwner(path, userPrincipal);
            System.out.println("Owner: " + Files.getOwner(path));
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


  移动文件有一些地方需要注意,首先是如果移动一个文件夹,文件夹和其子文件夹都会被移动,跨磁盘移动的文件夹时,目标文件夹必须是空的,否则会有DirectoryNotEmptyException异常抛出。
 
  如果我们移动文件的时候使用了StandardCopyOption.ATOMIC_MOVE选项,其他所有选项就都会被忽略,并且如果目标文件已经存在,老文件既不会被替换也不会有IOException异常抛出,结果和具体的系统实现有关。如果移动文件不能被原子性的完成,AtomicMoveNotSupportedException异常会被抛出。


    public static void main(String[] args) {
        
        try {
            
            Path sourceFile = Paths.get("D:/home/projects/note.txt");
            Path destinationFile = Paths.get("D:/home/sample/note.txt");
            Files.move(sourceFile, destinationFile, StandardCopyOption.REPLACE_EXISTING);
            
            System.out.println("File moved successfully!");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



  删除文件可以使用Files的delete和deleteIfExists这两个方法。顾名思义,当文件不存在时deleteIfExists的删除结果为false。如果要删除一个文件夹,文件夹必须是空的,或者结合使用SimpleFileVisitor来将文件夹下所有内容都删除。

    public static void main(String[] args) {
        
        try {
            
            Path sourceFile = Paths.get("D:/home/projects/note_bak1.txt");
            boolean result = Files.deleteIfExists(sourceFile);
            if (result) {
                System.out.println("File deleted successfully!");
            }
            
            sourceFile = Paths.get("D:/home/projects/note_bak2.txt");
            Files.delete(sourceFile);
            System.out.println("File deleted successfully!");

        } catch (NoSuchFileException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



  至此我们可以看到,Java7中复制删除或移动文件还是比较简单的,避免了之前过于复杂的API,而且大部分功能都是通过Files的静态方法实现的,对于我们使用非常方便。但文件的操作涉及到具体不同的操作系统是对文件的管理方式,因此我们还要对操作系统有一定的了解并正确使用不同的操作参数,才能更好的运用Java7中提供的这些API。
分享到:
评论

相关推荐

    java私塾跟我学系列-java篇

    4. **字符串处理**:Java中的String类是非常重要的,会涉及字符串的创建、操作方法,以及StringBuilder和StringBuffer的使用。 5. **集合框架**:Java集合框架包括List、Set、Map接口及其实现类,如ArrayList、...

    java学习教材(java私塾跟我学系列--java篇)

    ### Java学习教材(Java私塾跟我学系列--Java篇)知识点总结 #### 一、Java的历史与发展 - **Java的起源**:Java起源于Sun公司的Green项目,最初目的是为家用消费电子产品开发分布式代码系统。该项目起初尝试使用...

    Java语言基础教程-Java NIO流篇2

    例如,FileChannel用于文件操作,它支持映射文件到内存(Memory-Mapped File)以提高读写速度;SocketChannel则用于网络通信,可以实现TCP连接的读写。 第5节会进一步深入,探讨通道的使用技巧和高级特性。这可能...

    mysql-connector-java-8.0.22.jar

    本篇文章将深入探讨MySQL Connector/J 8.0.22及其在Java开发中的应用。 首先,MySQL Connector/J是MySQL官方提供的开源JDBC驱动,它完全符合JDBC 4.2规范,支持Java 8及更高版本。这个版本8.0.22包含了针对MySQL ...

    JDK7新特性(完整篇)

    Java Development Kit (JDK) 7 是 Java 编程语言的一个重大更新,包含了多项新特性,旨在提升开发者的效率、程序的性能以及对现代计算环境的支持。以下是对这些特性的详细解析: 1. **JDK7新特性<一>概述** JDK7的...

    eclipse-java-2021-09-R-linux-gtk-x86_64.tar.gz

    本篇将详细解析"Eclipse IDE for Java Developers",即2021年9月发布的版本,具体文件为“eclipse-java-2021-09-R-linux-gtk-x86_64.tar.gz”,针对Linux x86_64架构的系统。 首先,Eclipse Java版是专为Java开发者...

    java1.7 特性实现

    在本篇文章中,我们将深入探讨Java 7的一些核心特性,并通过实际代码示例来理解它们的工作原理。 1. **自动资源管理 (try-with-resources)** Java 7引入了一个新的语法结构——`try-with-resources`,用于更有效地...

    Java语言程序设计 基础篇-进阶篇源码

    这个压缩包文件"Java语言程序设计 基础篇-进阶篇源码"显然是一个关于学习Java编程的资源集合,涵盖了从基础到进阶的全过程。下面我们将详细探讨Java编程的一些关键知识点。 首先,基础篇通常会涵盖以下内容: 1. *...

    mysql-connector-java-8.0.30-jar包

    4. **jar 文件格式**: JAR(Java Archive)文件是 Java 类库的一种打包形式,它包含了一系列的 .class 文件、相关的元数据以及资源文件。MySQL Connector/J 的 jar 文件包含了驱动所需的全部类和资源,Java 应用通过...

    java高级特性 - io流.pdf

    总的来说,Java IO流是进行文件操作和网络通信的强大工具。掌握Java IO流的使用能够帮助开发者高效地处理数据输入输出,以及实现更加复杂的应用程序。在开发中,正确地使用Java IO流不仅可以提高程序的性能,还可以...

    Java语言程序设计-基础篇、进阶篇(原书第8版).pdf

    最后,基础篇会介绍输入输出流和文件操作,这是进行数据读写的重要技能。 进阶篇则更注重提升编程技巧和解决实际问题的能力。这部分将涵盖类的高级特性,如封装、继承和多态,这些是理解面向对象编程的关键。接口和...

    java-tutorial-2008-03-14

    4. **集合框架**:Java集合框架是存储和操作对象的重要工具。ArrayList、LinkedList、HashSet、HashMap等都是常用的集合类,我们将探讨它们的用法和各自的特点。 5. **输入/输出(I/O)系统**:Java提供了丰富的I/O...

    java访问共享文件

    9. **异步访问**:如果需要在多线程环境中高效处理文件操作,可以考虑使用Java的CompletableFuture或者ExecutorService来实现异步访问。 10. **测试和调试**:在实际应用中,需要充分测试各种情况,包括网络波动、...

    JAVA操作XML文件

    这篇博客文章“JAVA操作XML文件”可能涵盖了如何在Java环境中解析、创建和修改XML文档的核心概念。以下是相关的知识点详解: 1. **DOM解析器**: - DOM(Document Object Model)是W3C的标准,它将XML文档转化为一...

    java进阶/JDK 7、8新特性

    本篇主要关注JDK 7和8两个重要版本的新特性。 首先,JDK 7,是Java发展历程中的一个重要里程碑,它在2011年发布,引入了多项显著的改进。其中最重要的特性之一是“Try-with-resources”语句,这使得资源管理变得...

    JAVA程序员必读--基础篇chm

    9. **输入/输出流**:Java的IO流系统允许程序员处理输入和输出,包括文件操作、网络通信等。InputStream和OutputStream用于处理字节流,Reader和Writer则处理字符流。 10. **多线程**:Java内置了对多线程的支持,...

    java技能百练--游戏篇

    首先,Java语言在游戏开发中的优势在于其跨平台兼容性,Java的"一次编写,到处运行"特性使得游戏可以在不同的操作系统上运行,这极大地扩大了潜在玩家群体。此外,Java拥有丰富的库和框架,如LWJGL(Lightweight ...

    java程序员必读--基础篇

    I/O流是处理输入输出的关键,Java提供了丰富的流类库,如FileInputStream和FileOutputStream用于文件操作,BufferedReader和PrintWriter用于字符流处理,网络编程中的Socket和ServerSocket则用于网络数据交换。...

    Java语言程序设计-基础篇-进阶篇源码

    8. **输入/输出流**:文件操作,字节流和字符流,以及缓冲流的使用。 在进阶篇中,进一步探讨了以下高级主题: 1. **集合框架**:ArrayList、LinkedList、HashSet、HashMap等容器的使用,以及泛型的概念和应用。 2...

Global site tag (gtag.js) - Google Analytics