Java 从FileOutputStream获取文件名

Java 从FileOutputStream获取文件名,java,io,fileoutputstream,Java,Io,Fileoutputstream,有没有办法从FileOutputStream或FileInputStream获取文件名 看来答案是否定的: 没有公共方法返回流构造中使用的文件或字符串 编辑:同样适用于FileInputStream 这个特性不是由开箱即用的文件输入/输出流提供的,但是没有什么可以阻止您编写自己的子类来存储文件(或文件名)并为其提供getter 我建议为此实现一些FileNameAware接口),因为I/O流通常由InputStream/OutputStream抽象类引用,以避免将应用程序与特定实现耦合起来。

有没有办法从
FileOutputStream
FileInputStream
获取文件名

看来答案是否定的:

没有公共方法返回流构造中使用的
文件
字符串


编辑:同样适用于
FileInputStream

这个特性不是由开箱即用的文件输入/输出流提供的,但是没有什么可以阻止您编写自己的子类来存储文件(或文件名)并为其提供getter


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

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

为了解决这个问题,我使用了
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());
String location=“some.relative.path.txt”;
文件=新文件(位置);
FileOutputStream f=新的FileOutputStream(文件);
字符串问题=“标题+”;
字符串finalSource=HTMLWrapper.HTML\u START+question+htmlContent;
f、 写入(finalSource.getBytes());
f、 冲洗();
f、 close();
System.out.println(“该报告现在可在“+file.getAbsolutePath()上获得”);

可能,有反射:Tom G回答是正确的,即没有获取路径的API。但是,如果您像我一样被一个无法更改且无法通过任何其他方式获取文件名的框架所困扰,那么您可以使用反射来获取路径(在我的情况下,我需要它来进行调试)

显然,FileOutpuStream的实现可能会随着时间的推移而改变,而这段代码可能会中断。此外,为了清晰起见,我省略了上面代码段中异常的处理

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

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

这是不可能的,即使在原则上也是如此。问题的假设是,每个文件输入流都与一个具有一个名称的文件相关联。对于POSIX系统,后一种假设是错误的。对于POSIX系统,一个文件可以有任意数量的名称(硬链接),包括零。对于临时文件,零名称的情况非常常见,以确保在程序退出时删除临时文件

我已经编写了大量的文件IO代码,从来都不需要这个功能。你要求它表明你有一个设计缺陷。也就是说,您有一个XY问题

  • 代码几乎没有理由将流对象的引用类声明为文件流。IO代码可以使用InputStream或OutputStteam。事实上,作为接口编程的一部分,它应该支持对IO代码进行廉价的单元测试(通过使用简单的字节数组流作为模拟对象)
  • 您是否希望在某些日志消息中使用文件名?如果是这样,这表明您试图在程序层次结构中将文件IO错误记录得太低。也许您捕获IOExceptions太早了,而不是让它们传播到程序的更高部分,因为程序知道IO是文件IO,并且知道文件名

@Stephen-我阅读了文档,但只是想确认我没有遗漏任何内容。可能是因为文件(out/In)的输入流在这里并不重要,因为您持有文件。如果该方法只返回一个流,那么您就没有机会(直接使用FileInputStream)检索底层文件或locationEJP,这是错误的。有这样一个领域。我刚刚在Java1.8.0_112-b16下测试了它。这里的完整代码:import java.io.FileOutputStream;导入java.lang.reflect.Field;公共类FileOutputStreamTest{public static void main(字符串args[])引发异常{FileOutputStream outputStream=new FileOutputStream(“./FileOutputStreamTest.java”);字段pathField=FileOutputStream.class.getDeclaredField(“path”);pathField.setAccessible(true);字符串路径=(String)pathField.get(outputStream);System.out.println(“path=“+path”);}}除此之外,这不是重点。你的否决票完全不合适。如果“路径”不存在,则会有另一个具有不同名称的字段执行相同的操作。我的观点是,使用反射获取信息是可能的,但不推荐使用反射。为什么会有另一个领域?它不需要构造函数之外的路径。jdk1.6不需要它。EJP,我相信你是对的。我检查了1.7中的代码,但它不在那里。路径名是暂时的,过去不需要持久化。从1.8开始,它存储在变量“path”中,但我还没有检查代码以了解为什么会这样做。我已经纠正了一半,我很高兴1.8中有了这个“奖金”,因为它帮助我调试了我的问题。谢谢你的意见。是的,这在原则上和实践上都是可能的。创建完所有流后,流指向一个特定的文件。只要把它还给我,你就准备好了