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++有垃圾收集机制??不要乱说.

JVM 是应用对象引用图来进行对象回收的。
因此,回收对象的依据是:
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流临时变量问题的主要内容,如果未能解决你的问题,请参考以下文章

JAVA不用临时变量交换两个变量的值

控制 java.io.tmpdir 的环境变量?

InMemory:在内存中创建临时表和表变量

Java临时环境变量配置

window配置临时环境变量

临时环境变量怎么设置