从FileOutputStream获取文件名

46

如何从FileOutputStreamFileInputStream中获取文件名?

5个回答

35

3
@Stephen- 我已经阅读了文档,但只是想确认我没有漏掉任何内容。 - Ebbu Abraham

16

这个功能不是由开箱即用的文件Input/Output-Stream提供的,但你可以编写自己的子类来存储文件(或文件名),并提供一个getter方法。

我建议为此实现一些FileNameAware接口,因为I/O Streams通常使用InputStream/OutputStream抽象类引用,以避免将应用程序与特定实现耦合。


15

可能,通过反射实现:Tom G 的回答是正确的,即没有 API 可以获取路径。但是,如果你像我一样被困在一个无法更改且无法通过其他方式获取文件名的框架中,你可以使用反射来获取路径(在我的情况下,我需要用于调试目的)。

Field pathField = FileOutputStream.class.getDeclaredField("path");
pathField.setAccessible(true);
String path = (String) pathField.get(outputStream);

显然,FileOutputStream的实现可能随着时间而改变,导致此代码失效。另外,上面的代码片段中我省略了异常处理以清晰明了。

在1.6和1.7中不可用,已确认1.8中可用。


EJP,你错了。这个字段是存在的。我在Java 1.8.0_112-b16下测试过了。完整代码在此: - Hans Deragon
导入java.io.FileOutputStream; 导入java.lang.reflect.Field;public class FileOutputStreamTest { public static void main(String args[]) throws Exception { FileOutputStream outputStream = new FileOutputStream("./FileOutputStreamTest.java"); Field pathField = FileOutputStream.class.getDeclaredField("path"); pathField.setAccessible(true); String path = (String) pathField.get(outputStream); System.out.println("path=" + path); } } - Hans Deragon
4
此外,这不是重点。你的投票完全不合适。如果“路径”不存在,将会有另一个具有不同名称的字段可以执行相同的操作。我想表达的是,使用反射可以获取信息,尽管这并不被推荐。 - Hans Deragon
1
好的,不在JDK 1.6或.7中。为什么还需要另一个字段?它不需要构造函数外的路径。JDK 1.6不需要它。 - user207421
EJP,我相信你是对的。我在1.7中检查了代码,但没有找到它。路径名是瞬态的,以前不需要持久化。从1.8开始,它存储在变量“path”中,但我还没有检查代码以找出为什么这样做。我半正确地站起来,很高兴我们在1.8中有这个“奖励”,因为它帮助我调试问题。感谢您的意见。 - Hans Deragon

3
即使在原则上也不可能做到。问题的假设是每个文件输入流都与一个具有一个名称的文件相关联,但对于 POSIX 系统而言,后一个假设是错误的。对于 POSIX 系统来说,一个文件可以有任意数量的名称(硬链接),包括零个。零个名称的情况对于临时文件非常常见,以确保在程序退出时删除临时文件。
我已经编写了大量的文件 IO 代码,并且从未需要过这个功能。你提出这个需求表明你的设计存在缺陷,即你遇到了 XY 问题。
以下是一些建议: - 几乎没有理由让代码声明对流对象引用的类为文件流。IO 代码可以使用 InputStream 或 OutputStteam。事实上,它应该这样做,作为面向接口编程的一部分,以及为了能够使用简单的字节数组流作为模拟对象进行廉价的单元测试。 - 你是否希望在某些日志消息中使用文件名?如果是,那么这表明你正在尝试在程序层次结构的较低部分记录文件 IO 错误。也许你将 IOException 捕获得太早了,而不是让它们传播到程序的更高部分,这些部分知道 IO 是文件 IO 并知道文件的名称。

2
原则上和实际上都是可以的。毕竟,流被创建时指向特定文件。只需返回它,你就完成了。 - RecursiveExceptionException

2

我的回答有点晚。在编写代码时,我遇到了同样的问题。

为了解决这个问题,我使用了FileOutputStream(File file)而不是FileOutputStream(String location),因为我可以使用file.getAbsolutePath()。请参见下面的示例片段。

String location = "some.relative.path.txt";
File file = new File(location);
FileOutputStream f = new FileOutputStream(file);
String question = "<h3>"+header+"</h3>";
String finalSource = HTMLWrapper.HTML_START+question +htmlContent;
f.write(finalSource.getBytes());
f.flush();
f.close();
System.out.println("The report is now available at"+file.getAbsolutePath());

10
可能是因为在这种情况下,File(Out/In)putStream并不重要,因为您持有该文件。如果该方法仅返回一个流,则无法使用直接的FileInputStream方法检索基础文件或位置。 - Stephane Toussaint

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接