java IO流临时变量问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java IO流临时变量问题相关的知识,希望对你有一定的参考价值。
比方说我有一个方法 void print(String s),这个方法需要一个String类型的对象,那么当我调用完print(new String("AAA"))的时候,s这
个形参会析构,那么它指向的"AAA"字符串这个对象就变为垃圾内存了.
在io类里面比如BufferedReader in=new BufferedReader(new FileReader("filename.txt"));这里FileReader
这根管道接在filename.txt文件上,外面套了BufferedReader这根管道,那么在这句话执行完之后new FileReader("filename.txt")这个对象会
不会变为垃圾内存,因为这句话已经执行完毕了.
如果new FileReader("filename.txt")变为垃圾内存的化,刚好这时候垃圾内存回收运行了,把new FileReader("filename.txt")这个对象
给析构了,那么in这个对象还能进行读操作吗?没有里面的那根管道外面的管道还能不能使用.我很疑惑.
如果new FileReader("filename.txt")不变为垃圾内存的化,跟上面说的 void print(String s)方法的例子又不一致.
什么c++风格,c++有垃圾收集机制??不要乱说.
因此,回收对象的依据是:
1. 没有直接引用或影子引用。
2. 排除无效的循环引用(经典算法阿)。
new FileReader("filename.txt")产生对象FileReader ,该参数是传递给BufferedReader 的。所以BufferedReader -> FileReader
直到BufferedReader 被销毁时,才会销毁FileReader。
而对于你上面举的String例子,因为用的是字符串常量,所以可能在JVM里还存在引用该常量的对象引用,可能不会被回收。
另外,所谓的C++风格,是说你提的问题有点像C++程序员的思考风格,Java的人一般不关心这些的,呵呵。 参考技术A 问题好像c++的风格,在方法执行完毕后,垃圾收集器会在某一时间收集不在使用的对象占用内存,in是BufferedReader的实例,会保留一个Reader对象句柄,就是new FileReader("filename.txt"),所以还可以
继续使用的!
控制 java.io.tmpdir 的环境变量?
【中文标题】控制 java.io.tmpdir 的环境变量?【英文标题】:Environment variable to control java.io.tmpdir? 【发布时间】:2010-12-27 19:18:21 【问题描述】:我已经使用了TMP
环境变量来控制诸如 gcc 将其写入临时文件的位置,但我似乎找不到 java 的 createTempFile API 的等效项。
这样的环境变量存在吗?
【问题讨论】:
实际链接是java.sun.com/javase/6/docs/api/java/io/…, java.lang.String, java.io.File) 当我把那个 URL 放进去(或者当我用括号替换括号时) *** 没有做正确的事情%28 和 %29)。我知道使用短网址很糟糕,但我认为这总比没有链接要好。 我修复了链接。所以做正确的事就好了。 谢谢。我想诀窍也是用 %20 替换空格 我所做的只是点击您的链接,从浏览器的地址栏中复制 URL,然后将其粘贴到您的短链接所在的帖子中。 【参考方案1】:根据java.io.File
Java Docs
默认临时文件目录由系统属性 java.io.tmpdir 指定。在 UNIX 系统上,该属性的默认值通常是“/tmp”或“/var/tmp”;在 Microsoft Windows 系统上,它通常是“c:\temp”。调用 Java 虚拟机时,可以为该系统属性赋予不同的值,但不保证对该属性的编程更改对该方法使用的临时目录有任何影响。
要指定java.io.tmpdir
系统属性,你可以调用JVM如下:
java -Djava.io.tmpdir=/path/to/tmpdir
默认情况下,此值应来自 Windows 系统上的 TMP
环境变量
【讨论】:
这不能回答我的问题。是否有控制这个的环境变量? 尽管您进行了编辑,Bryan,java.io.tmpdir 绝对不遵循 Mac 或 Ubuntu 上的 TMPDIR 环境变量(在 6.06 上测试)。 Oy 和另一个编辑,让所有这些 cmets 看起来很荒谬。 @Zach。答案是特定于平台的。 没那么简单,这个答案仍然不正确。在 Windows 上,java.io.tmpdir
是通过使用 Windows SDK 函数 GetTempPath
(msdn.microsoft.com/en-us/library/aa364992%28VS.85%29.aspx) 定义的,如果前面的每一个都没有定义,它将解析为 TMP 或 TEMP 或 USERPROFILE 或 Windows 目录。【参考方案2】:
嗯——因为这是由 JVM 处理的,所以我深入研究了 OpenJDK VM 源代码,认为 OpenJDK 所做的可能模仿了 Java 6 和之前所做的。除了在 Windows 上之外,还有其他方法可以做到这一点,这并不令人放心。
在Windows 上,OpenJDK 的get_temp_directory()
函数对GetTempPath()
进行Win32 API 调用;这就是在 Windows 上,Java 反映 TMP
环境变量的值的方式。
在Linux 和Solaris 上,相同的get_temp_directory()
函数返回静态值/tmp/
。
我不知道实际的 JDK6 是否遵循这些确切的约定,但从列出的每个平台上的行为来看,它们似乎确实如此。
【讨论】:
要清楚,您看到的是在 JVM 创建系统属性时为“java.io.tmpdir”属性提供 默认值 的本机代码目的。这将被(例如)“-Djava.io.tmpdir=...”选项覆盖。 @StephenC,是的,这就是重点——OP 正在寻找在没有自己设置的情况下如何设置属性的默认值(通过-Djava.io.tmpdir
命令行选项JVM),以及该默认值是否完全受环境值的影响。正如人们所观察到的,在 Windows 上它受到环境变量 TMP
的影响,但不清楚是否存在其他操作系统的未知变量。看起来没有,至少考虑到我们对 OpenJDK 的了解。
不错的答案,但在 Windows 上 GetTempPath()
不受 TMP
环境变量的影响:msdn.microsoft.com/en-us/library/aa364992%28VS.85%29.aspx
我已经看到,在 Solaris Sun JDK 上,该值为 /var/tmp/
(带有前导斜杠),甚至还有 bug#4391434。还有for Mac OS and Linux it is /tmp
——真是一团糟!
@Znik 可以与 oracle-java8-jdk=8u102
(linux) 一起使用【参考方案3】:
您可以设置您的_JAVA_OPTIONS
环境变量。例如,在 bash 中,这可以解决问题:
export _JAVA_OPTIONS=-Djava.io.tmpdir=/new/tmp/dir
我将它放入我的 bash 登录脚本中,它似乎可以解决问题。
【讨论】:
虽然这似乎适用于 Linux 和 MacOSX,但它有一个不幸的副作用,即在每次 java 启动时打印一些额外的输出:Picked up _JAVA_OPTIONS:
这完全混淆了我们的构建过程。
我确实对这个答案投了赞成票,因为它确实回答了用户的问题,并且用户没有指定操作系统或想要避免任何其他副作用。我相信这应该被设置为最佳答案
这个变量似乎特定于 Sun JVM -- f.e. IBM J9 JVM 不支持它;它确实支持 IBM_JAVA_OPTIONS
@sendmoreinfo,据我所知,它适用于 Sun/Oracle 和 OpenJDK。
根据this answer关于环境变量的区别,JAVA_TOOL_OPTIONS
更便携。【参考方案4】:
使用
$ java -XshowSettings
Property settings:
java.home = /home/nisar/javadev/javasuncom/jdk1.7.0_17/jre
java.io.tmpdir = /tmp
【讨论】:
【参考方案5】:它不是环境变量,但仍然可以让您控制临时目录:
-Djava.io.tmpdir
例如:
java -Djava.io.tmpdir=/mytempdir
【讨论】:
【参考方案6】:要清楚这里发生了什么:
设置临时目录位置的推荐方法是设置名为“java.io.tmpdir”的系统属性,例如通过将选项-Djava.io.tmpdir=/mytempdir
赋予java
命令。该属性也可以在程序中通过调用System.setProperty("java.io.tmpdir", "/mytempdir)
来更改...模沙箱安全问题。
如果您没有在启动时显式设置“java.io.tmpdir”属性,JVM 会将其初始化为 平台特定 默认值。对于 Windows,默认值是通过调用 Win32 API 方法获得的。对于 Linux / Solaris,默认值显然是硬连线的。对于其他 JVM,它可能是别的东西。
根据经验,“TMP”环境变量适用于 Windows(使用当前 JVM),但不适用于其他平台。如果您关心可移植性,则应显式设置系统属性。
【讨论】:
【参考方案7】:在 UNIX 终端上使用以下命令:
java -XshowSettings
这将显示所有 java 属性和系统设置。
在此查找java.io.tmpdir
值。
【讨论】:
【参考方案8】:如果您查看 JDK 的源代码,您可以看到对于 unix 系统,该属性是在 compile 时间从 paths.h 或 hard coded 读取的。对于windows,来自win32 的函数GetTempPathW
返回tmpdir
名称。
对于 posix 系统,您可能希望 standard TMPDIR
能够工作,但事实并非如此。你可以通过运行TMPDIR=/mytmp java -XshowSettings
来确认TMPDIR
没有被使用
【讨论】:
【参考方案9】:我们可以改变默认的tomcat文件上传位置,如
我们必须设置环境变量,例如:CATALINA_TEMPDIR = YOUR FILE UPLOAD LOCATION。 这个位置会改变这里的路径:java -Djava.io.tmpdir=/path/to/tmpdir
【讨论】:
请阅读How to answer 并根据指南中的指南更新您的答案。以上是关于java IO流临时变量问题的主要内容,如果未能解决你的问题,请参考以下文章