`

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的跨平台特性,是相对于其他编程语言而言的。...其中,Java运行系统又称Java虚拟机(JVM),它实现了Java解释器的功能,只要不同的操作系统上安装了对应版本的JVM,就可以解释执行Java字节码文件,运行Java程序。

    Java技术教程.基础篇part1

    共计十七章,前十章主要介绍了Java 2基本语法概念和面向对象的编程思想,其中包括运算符、流程控制、数组、字符串处理、异常、I/O及文件操作、对象的串行化以及面向对象的特性。后面七章从多方面介绍了Java 2编程...

    Java技术教程.基础篇

    第九章 java输入、输出及文件操作 第十章 对象串行化 第十一章 线程 第十二章 图形用户界面 第十三章 用Swing创建用户界面 第十四章 Java小应用程序\(Applet和JApplet\) 第十五章 集合框架 第十六章 网络通信 第十七...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    第7章 Java中的方法——给汽车丰富多彩的功能 154 教学视频:2小时55分钟 7.1 方法:让汽车动开动 154 7.1.1 引出问题:开动汽车 154 7.1.2 那么,方法到底是什么呢? 155 7.1.3 方法调用过程初探 156 7.2 ...

    Visual C++实践与提高-COM和COM+篇『PDF』

    因文件超过20M不能上传,所以拆分为两个文件分次上传 第1章 COM背景知识 1.1 COM的起源 1.1.1 软件业面临的挑战 1.1.2 传统解决方案 1.1.3 面向对象程序设计方法 1.1.4 最终解决方案:组件软件 1.1.5 面向对象的...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    第7章 Java中的方法——给汽车丰富多彩的功能 154 教学视频:2小时55分钟 7.1 方法:让汽车动开动 154 7.1.1 引出问题:开动汽车 154 7.1.2 那么,方法到底是什么呢? 155 7.1.3 方法调用过程初探 156 7.2 ...

    Java典型模块

    第4篇 文件操作和访问 18.1 文件属性查看器原理 18.1.1 项目结构框架分析 18.1.2 项目功能业务分析 18.2 文件属性查看器项目 18.2.1 实现显示文件信息的自定义窗口 18.2.2 自定义窗口的显示 18.3 知识点扩展——文件...

    Java JNI完全手册

     JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。  JAVA通过JNI调用本地方法,而本地方法是以...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    本书是第II卷,以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用Java进行桌面程序开发各个方面的知识和技巧,主要包括Java语法与面向对象技术、Java高级应用、窗体与控件应用、文件操作典型...

    JAVA在SQLite嵌入式数据库中的应用.rar

    SQLite 作为一个开源的嵌入式数据库产品,具有系统开销小,检索效率高的特性,适用于手机、PDA、机顶盒设备等电器,并且作为嵌入式数据库在可下载的消费类应用程序中运行的很好。这篇文章介绍嵌入式数据库产品SQLite...

    Java开发技术大全 电子版

    第4篇Java中的高级技术 第8章Java的多线程机制266 8.1线程的概念266 8.1.1多线程的特点266 8.1.2线程的状态267 8.2Thread类268 8.2.1Thread类的构造方法268 8.2.2Thread类的常用方法268 8.3多线程程序的编写...

    《程序天下:J2EE整合详解与典型案例》光盘源码

    8.4 JUnit的新特性 8.4.1 改变测试方法的命名方式 8.4.2 不再继承TestCase 8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    8.4 JUnit的新特性 8.4.1 改变测试方法的命名方式 8.4.2 不再继承TestCase 8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    8.4 JUnit的新特性 8.4.1 改变测试方法的命名方式 8.4.2 不再继承TestCase 8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS ...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    8.4 JUnit的新特性 8.4.1 改变测试方法的命名方式 8.4.2 不再继承TestCase 8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS ...

Global site tag (gtag.js) - Google Analytics