`
cucaracha
  • 浏览: 140281 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A8f3fa2f-18ce-3862-897a-5d2209197c90
Java NIO.2
浏览量:87287
7a076ba7-8ec8-3241-aa3c-67bb2f7856a2
Java EE 7 简明教...
浏览量:36321
社区版块
存档分类
最新评论

[NIO.2] 第二十八篇 创建临时目录和文件

阅读更多
临时目录是用于存储临时文件的目录。临时目录的位置依赖操作系统。在 Windows 中,临时目录通过 TEMP 环境变量定义,通常位置是  C:\Temp、%Windows%\Temp,或者根据每个用户放到  Local Settings\Temp。在 Linux/Unix 中,全局临时目录在 /tmp 和 /var/tmp。

创建临时目录

NIO.2 提供了  createTempDirectory() 方法用于创建临时目录。这个方法会在系统默认临时目录位置创建临时目录。可以调用有两个参数的方法,第一个参数是临时目录命名前缀,可以为空,第二个可选参数是创建目录时设置的属性列表。下面的代码将创建两个临时目录,一个使用了前缀,另一个没有前缀:

String tmp_dir_prefix = "nio_"; 
try { 
    //passing null prefix 
    Path tmp_1 = Files.createTempDirectory(null); 
    System.out.println("TMP: " + tmp_1.toString()); 

    //set a prefix 
    Path tmp_2 = Files.createTempDirectory(tmp_dir_prefix); 
    System.out.println("TMP: " + tmp_2.toString()); 
 } catch (IOException e) { 
    System.err.println(e); 
 }


下面是在我机器上的输出结果:

TMP: C:\Users\Leo\AppData\Local\Temp\3238630399269555448 
TMP: C:\Users\Leo\AppData\Local\Temp\nio_1097550355199661257


注:如果你不知道你的机器临时目录位置,可以使用下面的代码获取:

//output: C:\Users\Leo\AppData\Local\Temp\ 
String default_tmp = System.getProperty("java.io.tmpdir"); 
System.out.println(default_tmp);


也可以设置临时目录存放的位置,createTempDirectory() 方法除了前缀和属性列表外,还接受临时目录存放位置的 Path 对象。下面的代码演示了在  C:\rafaelnadal\tmp 目录下创建临时目录:

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp/"); 
String tmp_dir_prefix = "rafa_"; 
… 
try { 
    //create a tmp directory in the base dir 
    Path tmp = Files.createTempDirectory(basedir, tmp_dir_prefix); 
    System.out.println("TMP: " + tmp.toString()); 
} catch (IOException e) { 
    System.err.println(e); 
}


可能的输出结果如下:

TMP: C:\rafaelnadal\tmp\rafa_1753327229539718259


使用 shutdown 钩子删除临时目录

大多数操作系统都可以自动删除临时目录(如果不可以,那么可以安装自动清理软件)。但是有的时候,你需要以编码的方式删除临时目录。为此,你可以使用 shutdown 钩子程序,这主要用于系统停止运行时进行资源清理和保存。这个钩子程序可以使用 Thread 类来实现,在 JVM 停止的时候会自动调用 run() 方法。

下面看看样例代码:

Runtime.getRuntime().addShutdownHook(new Thread() { 

@Override 
public void run() { 
  System.out.println("Shutdown-hook activated ..."); 

  //… here, cleanup/save resources  

  System.out.println("Shutdown-hook successfully executed ..."); 
  } 
});


利用钩子程序来删除临时目录是一个比较好的选择。但是,目录在非空的情况下是不允许删除的,因此你需要递归删除每一层的目录和文件。为了简单,我们这里的例子只演示删除临时目录下只有临时文件和空的临时目录(大多数真实情况也是如此)。

下面的例子先创建了临时目录,然后利用 shutdown 钩子程序删除临时目录下的内容:

final Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp/"); 
final String tmp_dir_prefix = "rafa_"; 

try { 
//create a tmp directory in the base dir 
final Path tmp_dir = Files.createTempDirectory(basedir, tmp_dir_prefix); 

Runtime.getRuntime().addShutdownHook(new Thread() { 

@Override 
public void run() { 
  System.out.println("Deleting the temporary folder ..."); 

  try (DirectoryStream<Path> ds = Files.newDirectoryStream(tmp_dir)) { 
       for (Path file : ds) { 
               Files.delete(file); 
       } 

   Files.delete(tmp_dir); 

   } catch (IOException e) { 
       System.err.println(e); 
   } 

   System.out.println("Shutdown-hook completed..."); 
 } 
}); 

//simulate some I/O operations over the temporary file by sleeping 10 seconds 
//when the time expires, the temporary file is deleted             
Thread.sleep(10000); 
//operations done 

} catch (IOException | InterruptedException e) { 
    System.err.println(e); 
}


注:上面的例子使用了 Thread.sleep() 方法来延长目录创建和 JVM 停止之间的时间,方便你进行观察整个创建和删除的过程。真实项目中,这里可以添加业务逻辑。

使用 deleteOnExit() 方法删除临时目录

另一个删除临时目录的方法是调用 File. deleteOnExit() 方法(非 NIO.2 的方法),这个方法会在 JVM 停止的时候删除文件或目录。因为这个方法会被每个临时目录和文件调用,那么将会占用很多内存,因此被认为不是一个很好的选择。

注:如果你的系统将要长时间运行或创建了很多临时目录/文件或临时目录/文件只是很短暂的使用,那么使用 deleteOnExit() 就是一个比较差的选择。这个方法会一直占用内存,并且不会释放,直到 JVM 停止。

下面的代码演示了如何使用 deleteOnExit():

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp/"); 
String tmp_dir_prefix = "rafa_"; 

try { 
    //create a tmp directory in the base dir 
    Path tmp_dir = Files.createTempDirectory(basedir, tmp_dir_prefix); 

    File asFile = tmp_dir.toFile(); 
    asFile.deleteOnExit(); 

    //simulate some I/O operations over the temporary file by sleeping 10 seconds 
    //when the time expires, the temporary file is deleted             
    //EACH CREATED TEMPORARY ENTRY SHOULD BE REGISTERED FOR DELETE ON EXIT 
    Thread.sleep(10000); 
    //operations done 

} catch (IOException | InterruptedException e) { 
   System.err.println(e); 
}


注:因为 deleteOnExit() 方法只能在 File 类上调用,因此需要先将 Path 对象通过 Path.toFile() 方法转换为 File 对象。

创建临时文件

在 NIO.2 中,可以调用  createTempFile() 方法在默认临时目录创建临时文件。这个方法有三个参数:临时文件的前缀(可为 null),临时文件的后缀名(如果设置为 null,那么默认值是 .tmp),用于在创建临时文件时设置文件属性的可选参数。

下面的代码将创建两个临时文件,一个使用默认的前缀和后缀,一个使用指定的前缀和后缀:

String tmp_file_prefix = "rafa_"; 
String tmp_file_sufix=".txt"; 
 
try { 
    //passing null prefix/suffix 
    Path tmp_1 = Files.createTempFile(null,null); 
    System.out.println("TMP: " + tmp_1.toString()); 
  
    //set a prefix and a suffix 
    Path tmp_2 = Files.createTempFile(tmp_file_prefix, tmp_file_sufix); 
    System.out.println("TMP: " + tmp_2.toString()); 
  
} catch (IOException e) { 
    System.err.println(e); 
}


上面的代码将会在系统默认位置创建临时文件,运行后输出如下:

TMP: C:\Users\Leo\AppData\Local\Temp\6873427319542945524.tmp 
TMP: C:\Users\Leo\AppData\Local\Temp\rafa_6168226983257408796.txt


你也可以在调用 createTempFile() 方法创建临时文件的时候指定临时文件所在的目录。这个方法除了前缀、后缀和可选的文件属性外,还接受一个 Path 类型的参数,用于指定临时目录位置。

下面的代码会将临时文件创建到  C:\rafaelnadal\tmp 目录中:

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp"); 
String tmp_file_prefix = "rafa_"; 
String tmp_file_sufix=".txt"; 
 
try { 
    Path tmp_3 = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix); 
    System.out.println("TMP: " + tmp_3.toString()); 
} catch (IOException e) { 
    System.err.println(e); 
}


运行后输出结果显示:

TMP: C:\rafaelnadal\tmp\rafa_512352743612949417.txt


使用 shutdown 钩子删除临时文件

和删除临时目录一样,也可以用 shutdown 机制删除文件,下面的例子会现在  C:\rafaelnadal\tmp 目录下创建临时文件,等待 10 秒钟后,JVM 停止运行并删除临时文件:

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp"); 
String tmp_file_prefix = "rafa_"; 
String tmp_file_sufix = ".txt"; 
 
try { 
    final Path tmp_file = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix); 
 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
    @Override 
    public void run() { 
    System.out.println("Deleting the temporary file ..."); 
 
    try { 
        Files.delete(tmp_file); 
    } catch (IOException e) { 
        System.err.println(e); 
    } 
 
    System.out.println("Shutdown hook completed..."); 
  } 
}); 
 
//simulate some I/O operations over the temporary file by sleeping 10 seconds 
//when the time expires, the temporary file is deleted             
Thread.sleep(10000); 
//operations done 
 
} catch (IOException | InterruptedException e) { 
    System.err.println(e); 
}


使用 deleteOnExit() 方法删除临时文件

和删除临时目录一样,也可以调用 deleteOnExit() 方法删除临时文件。下面的例子会现在  C:\rafaelnadal\tmp 目录下创建临时文件,等待 10 秒钟后,JVM 停止运行并删除临时文件:

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp"); 
String tmp_file_prefix = "rafa_"; 
String tmp_file_sufix = ".txt"; 
 
try { 
    final Path tmp_file = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix); 
 
    File asFile = tmp_file.toFile(); 
    asFile.deleteOnExit(); 
 
    //simulate some I/O operations over the temporary file by sleeping 10 seconds 
    //when the time expires, the temporary file is deleted             
    Thread.sleep(10000); 
    //operations done 
} catch (IOException | InterruptedException e) { 
    System.err.println(e); 
}


通过 DELETE_ON_CLOSE 删除临时文件

还有一个巧妙的用法是使用 DELETE_ON_CLOSE 选项。正如它名字描述的一样,它会在文件流关闭的时候删除文件。例如,下面的代码会使用 createTempFile() 方法在 C:\rafaelnadal\tmp 目录下创建临时文件,并且使用 DELETE_ON_CLOSE 选项打开文件流,在文件流关闭的时候,文件会被删除。

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp"); 
String tmp_file_prefix = "rafa_"; 
String tmp_file_sufix = ".txt"; 
Path tmp_file = null; 
try { 
    tmp_file = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix); 
} catch (IOException e) { 
    System.err.println(e); 
} 
try (OutputStream outputStream = Files.newOutputStream(tmp_file,  
                                      StandardOpenOption.DELETE_ON_CLOSE); 
     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) { 
     //simulate some I/O operations over the temporary file by sleeping 10 seconds 
     //when the time expires, the temporary file is deleted             
     Thread.sleep(10000); 
     //operations done 
} catch (IOException | InterruptedException e) { 
     System.err.println(e); 
}


你也可以不通过  createTempFile() 方法来模拟创建临时文件,只需要定义文件名,并使用 DELETE_ON_CLOSE 和 CREATE 选项联合创建文件流,如下所示:

String tmp_file_prefix = "rafa_"; 
String tmp_file_sufix = ".txt"; 
Path tmp_file = null; 
 
tmp_file = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp", tmp_file_prefix +  
                                                                "temporary" + tmp_file_sufix); 
 
try (OutputStream outputStream = Files.newOutputStream(tmp_file, StandardOpenOption.CREATE,  
                                                          StandardOpenOption.DELETE_ON_CLOSE); 
     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) { 
 
     //simulate some I/O operations over the temporary file by sleeping 10 seconds 
     //when the time expires, the temporary file is deleted             
     Thread.sleep(10000); 
     //operations done 
} catch (IOException | InterruptedException e) { 
     System.err.println(e); 
}


文章来源:http://www.aptusource.org/2014/04/nio-2-creating-temporary-directories-and-files/
0
0
分享到:
评论

相关推荐

    Java IO, NIO and NIO.2

    NIO.2还包含了许多其他的API扩展和改进,例如对符号链接的支持、文件属性访问、文件树遍历、WatchService等。 以上介绍了Java中的三种I/O机制。在实际开发中,它们各有适用场景。例如,Java IO适合进行传统的I/O...

    java NIO.zip

    多路复用器是选择器的另一种称呼,它能够监视多个通道上的事件,通过单个线程处理这些通道,减少了线程创建和销毁的开销,提高了系统的资源利用率。 6. **内存映射文件(Memory-Mapped Files)**: NIO允许将文件...

    Java IO, NIO and NIO.2(Apress,2015)

    Java I/O, NIO, and NIO.2 is a power-packed book that accelerates your mastery of Java's various I/O APIs. In this book, you'll learn about classic I/O APIs (File, RandomAccessFile, the stream classes ...

    NIO.2 入门,第 2 部分: 文件系统 API

    在Java的NIO.2(New IO 2.0)框架中,文件系统API提供了更加高效和灵活的方式来处理文件和目录。本篇我们将深入探讨NIO.2中的几个关键概念和类,包括`Files`, `Path`, `FileAttributes`, `DirectoryWatcher`以及`...

    Pro Java 7 NIO.2.pdf

    根据提供的文件信息,“Pro Java 7 NIO.2.pdf”由Anghel Leonard于2011年编写,主要介绍了Java 7中的新输入/输出(NIO)API,特别是NIO.2(JSR 203)所带来的增强功能。这本书通过一系列章节详细讲解了如何使用NIO.2...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    2. 缓冲区(Buffer):如ByteBuffer和FloatBuffer,作为数据的临时存储区域,支持批量读写操作。 3. 文件复制:通过通道和缓冲区的配合,实现高效的大文件复制。 4. 浮点数操作:使用FloatBuffer处理浮点数的读写。 ...

    Java IO, NIO and NIO.2 原版pdf by Friesen

    New I/O (NIO), and NIO.2 categories. You learn what each category offers in terms of its capabilities, and you also learn about concepts such as paths and Direct Memory Access. Chapters 2 through 5 ...

    优雅的操作文件:java.nio.file 库介绍.pdf

    为了解决这些问题,Java引入了`java.nio.file`库,这个库极大地提升了Java在文件操作方面的效率和易用性。 ### 1. Path路径 `java.nio.file.Paths`模块提供静态方法创建`Path`对象,代表文件系统中的路径。`Path`...

    Java I/O, NIO and NIO.2

    Java I/O, NIO, 和 NIO.2 是Java平台中处理输入/输出操作的核心组件,对于任何Java开发者来说,理解和掌握这些概念至关重要。本文将深入探讨这些技术,旨在提供一个全面而详尽的概述。 Java I/O(Input/Output)是...

    Java NIO 中英文版 + Pro Java 7 NIO.2

    2. **文件属性和文件观察者**:增加了获取和修改文件属性的API,以及文件观察者(WatchService),可以监听文件系统事件,如创建、删除、修改等。 3. **文件通道的锁**:支持文件的共享锁和独占锁。 4. **选择器的...

    java 在指定的目录下创建多个临时文件

    在Java编程语言中,创建多个临时...总结来说,Java提供了强大的文件操作功能,通过`File`和`Files`类,我们可以方便地在指定目录下创建多个临时文件。通过理解这些API,开发者能够灵活地满足各种临时文件存储的需求。

    java nio.pdf

    java nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava nio.pdfjava ...

    JDK1.7 之java.nio.file.Files 读取文件仅需一行代码实现

    JDK1.7 之 java.nio.file.Files 读取文件仅需一行代码实现 java.nio.file.Files 类是 JDK1.7 中引入的新的文件操作类,该类包含了许多有用的方法来操作文件。其中,Files.readAllBytes(Path) 方法可以将整个文件...

    nio.zip_NIO_NewIO_NIO.c_java NIO chm_java nio

    `java_nio_chm`指的是包含Java NIO相关内容的CHM(Compiled Help Manual)文件,这是一种Windows下的帮助文档格式,通常包含一系列的章节和索引,方便用户查阅。在这个文档中,你可以找到关于Java NIO类库的详细说明...

    Apress.Pro.Java.7.NIO.2.2011

    《Apress.Pro.Java.7.NIO.2.2011》这本书专注于讲解Java 7中的非阻塞I/O(Non-blocking I/O, NIO)和NIO 2的高级特性,是Java开发者深入理解这一关键领域的重要参考资料。NIO在Java平台中扮演着至关重要的角色,特别...

    java-nio.rar_NIO_java nio

    - `java.nio.file.Paths` 和 `Files` 类:提供文件操作的NIO接口,如读写文件、获取文件属性等。 5. **NIO在连接池中的应用** - **创建服务器端**:使用`AsynchronousServerSocketChannel`创建监听通道,接受...

Global site tag (gtag.js) - Google Analytics