不要在linux上使用java 7 Files的接口参数StandardOpenOption.DELETE_ON_CLOSE
来源:互联网 发布:数据库论坛 编辑:程序博客网 时间:2024/06/01 09:26
最近在看安全代码规范建议中提到关于如何删除创建的临时文件,推荐使用jdk7中的Files的函数,通过参数StandardOpenOption.DELETE_ON_CLOSE来控制
代码示例
BufferedWriter writer = Files.newBufferedWriter(tempFile, Charset.forName("UTF8"), StandardOpenOption.DELETE_ON_CLOSE)
只要当文件close掉,这个文件就会自动被系统删除,这样可以避免在一些场景下忘了删除产生的临时文件。
StandardOpenOption.DELETE_ON_CLOSE参数
我们来看代码StandardOpenOption.DELETE_ON_CLOSE参数在linux下究竟控制了什么,我们在java代码中看到了参数的控制阀
if (flags.deleteOnClose) { try { if (dfd >= 0) { unlinkat(dfd, path.asByteArray(), 0); } else { unlink(path); } } catch (UnixException ignore) { // best-effort } }
java的unlink函数
static void unlink(UnixPath path) throws UnixException { NativeBuffer buffer = copyToNativeBuffer(path); try { unlink0(buffer.address()); } finally { buffer.release(); } }
JNI unlink0函数
JNIEXPORT void JNICALLJava_sun_nio_fs_UnixNativeDispatcher_unlink0(JNIEnv* env, jclass this, jlong pathAddress){ const char* path = (const char*)jlong_to_ptr(pathAddress); /* EINTR not listed as a possible error */ if (unlink(path) == -1) { throwUnixException(env, errno); }}最后调用了系统unlink函数
unlink rm unlinkat remove的区别
我们通常会使用shell rm去删除文件,让我们先看看rm做了什么,通过strace来查看系统调用strace rm filepath会看到最后调用的函数unlinkat
unlink 和 unlinkat 的区别
unlinkat 可以通过参数AT_REMOVEDIR删除空的目录,其他的是和unlink一样
unlinkat(AT_FDCWD, "/tmp/test", AT_REMOVEDIR)
remove 和 unlink的区别
remove是unlink 和 rmdir 合集,区别也是在删除目录上
可以看到说参数StandardOpenOption.DELETE_ON_CLOSE 在linux上是调用了unlink删除了文件名,那么也就意味着你对这个文件的任何读写操作都是无效的。
Linux和windows的区别
参数StandardOpenOption.DELETE_ON_CLOSE在Linux和windows是不一样的实现,windows上只有调用了writer.close() 这个文件才会被删除,也就是windows上的open函数本身就带有文件属性FILE_FLAG_DELETE_ON_CLOSE,当显式的调用close,自然就会删除该文件,而如果进程退出也会删除这个文件。
总结:
参数StandardOpenOption.DELETE_ON_CLOSE对Linux 来说是无效的操作,虽然保证了文件的删除,但也违反了本身API的协议(需要调用close才能真实的删除文件)。
而且本身也没有实际意义,因为文件已经被删除了,那就意味着本身也无法向文件中写任何内容,那么创建临时文件的意义也不存在了。这个函数在windows上是实现的,而Linux中没有类似的内核函数去实现这样的功能。
File函数的方法deleteOnExit
File.deleteOnExit()
这个方法在jvm退出时添加了一个钩子,退出时删除文件。但是如果jvm没有正常退出呢?比如我们常用的信号退出,就没有办法正常删除文件。
StandardOpenOption.DELETE_ON_CLOSE这是需要在内核函数中去实现这个属性,而不是在jvm 应用层去实现,而jvm 在针对Linux 直接调用unlink 也是避免了问题的复杂化。
- 不要在linux上使用java 7 Files的接口参数StandardOpenOption.DELETE_ON_CLOSE
- Java web在Linux上取接口参数乱码问题
- 不要在linux上启用net.ipv4.tcp_tw_recycle参数
- 不要在linux上启用net.ipv4.tcp_tw_recycle参数
- 不要在linux上启用net.ipv4.tcp_tw_recycle参数
- 不要在linux上启用net.ipv4.tcp_tw_recycle参数
- 运行在Linux系统上的Java程序可能会出现"Too many open files"
- 在嵌入式Linux上使用CF接口的蓝牙模块
- 在嵌入式Linux上使用CF接口的蓝牙模块
- 在ARM linux上使用usb接口的触屏
- 在Linux上使用Java
- 在Linux上使用Java
- 在Linux不要使用 gethostbyname
- 如何在linux(ubuntu)上使用java的jni
- 在嵌入式Linux上使用CF接口的Modem (CDMA/GPRS)
- 在嵌入式Linux上使用CF接口的Modem (CDMA/GPRS)
- Java 工具(jmap,jstack)在linux上的源码分析(五) -F 参数的bug
- linux 工作队列上睡眠的认识--不要在默认共享队列上睡眠
- Android中Java和JavaScript交互
- Activiti 架构分析
- linux下gsoap的初次使用 (c)
- JS数组方法汇总 array数组元素的添加和删除
- GCD 深入理解(二)
- 不要在linux上使用java 7 Files的接口参数StandardOpenOption.DELETE_ON_CLOSE
- 解析Qt自带的Style示例
- Java io初探(1),使用java流复制文件
- 每个Java开发者都应该知道的5个JDK工具
- Android——SharedPreferences共享 参数 主要记录记住密码 用户名等
- 浏览器兼容
- inux下方便的录屏命令
- 2015年网址导航的十大关键词
- Matlab-------regexp正则表达式