Is there a way to get the file name from a FileOutputStream
or from FileInputStream
?

- 2,036
- 5
- 22
- 30
5 Answers
Looks like the answer is no:
http://download.oracle.com/javase/1.4.2/docs/api/java/io/FileOutputStream.html
http://docs.oracle.com/javase/7/docs/api/index.html?java/io/FileOutputStream.html
There are no public methods that return the File
or String
used in construction of the stream.
EDIT: The same holds for FileInputStream
.

- 5,783
- 15
- 70
- 117

- 12,620
- 2
- 44
- 56
This feature is not provided by the out-of-the-box File-Input/Output-Stream, but nothing stops you from writing your own subclass that stores the File (or fileName) and provides a getter for it.
I would suggest implementing some FileNameAware
interface for this), as I/O Streams are usually referenced with the InputStream
/ OutputStream
abstract classes to avoid coupling your application with specific implementations.

- 37,042
- 7
- 56
- 92
Possible, with reflection: Tom G answer is correct, i.e. there is no API to get the path. However, if you are stuck like me with a framework you cannot change and cannot get the filename by any other mean, you can use reflection to get the path (in my case, I needed that for debugging purposes).
Field pathField = FileOutputStream.class.getDeclaredField("path");
pathField.setAccessible(true);
String path = (String) pathField.get(outputStream);
Obviously, the implementation of FileOutpuStream could change with time and this code could break. Also, I omitted the handling of exceptions in the snippet above for clarity purposes.
Not available in 1.6 and 1.7 Confirmed available in 1.8.

- 504
- 1
- 7
- 17
-
EJP, you are wrong. There is such a field. I just tested it under Java 1.8.0_112-b16. Full code here: – Hans Deragon Nov 21 '16 at 18:03
-
import java.io.FileOutputStream; import 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 Nov 21 '16 at 18:04
-
4Beside, this is not the point. Your down voting is totally out of place. If "path" would not be there, there would be another field with a different name that would do the same. My point is that it is possible to fetch the information using reflection, though it is not recommended. – Hans Deragon Nov 21 '16 at 18:05
-
1OK, not in JDK 1.6 or .7. And why would there be another field? It doesn't need the path outside the constructor. JDK 1.6 didn't need it. – user207421 Dec 21 '17 at 07:33
-
EJP, I believe you are right. I checked the code in 1.7 and it is not there. The path name is transient and used to be not required to persist. Starting with 1.8, it is stored in the variable "path", but I have not checked the code to find out why the do this. I stand half corrected and I am glad that we have this "bonus" in 1.8 as it helped me debug my issues. Thank you for your input. – Hans Deragon Dec 21 '17 at 16:07
This is not possible, even in principle. The assumption of the question is that each file input stream is associated with one file that has one name. The latter assumption is wrong, for POSIX systems. For POSIX systems, a file can have any number of names (hard links), including zero. The case of zero names is quite common for temporary files, to ensure that the temporary file is removed on program exit.
I've written plenty of file IO code, and never needed this functionality. That you are asking for it suggests you have a design flaw. That is, you have an XY problem.
- There is almost no reason for code to declare the class of a reference to a stream object to be a file stream. IO code can use an InputStream or OutputStteam. Indeed, it should, as part of programming to an interface, and to enable cheap unit testing of your IO code (by enabling use of a simple byte array stream as a mock object).
- Are you perhaps hoping to use the filename in some log messages? If so, that suggests you are trying to log file IO errors too low in your program hierarchy. Perhaps you are catching IOExceptions too "early", rather than letting them propagate to higher parts of your program, which know that the IO is file IO and know the name of the file.

- 46,613
- 43
- 151
- 237
-
2Yes it would be possible in principle and in practice. After all the stream was created pointed at a particular file. Just return that and you're set – RecursiveExceptionException Aug 22 '18 at 18:39
My answer comes a little late. I hit the same issue when writing some code.
To get around it, I used a FileOutputStream(File file)
instead of FileOutputStream(String location)
because I can then do file.getAbsolutePath()
. See the example snippet below.
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());

- 3,739
- 21
- 40

- 13,584
- 6
- 55
- 88
-
10Maybe because the File(Out/In)putStream did not matter here as you hold the File. If the method only return a Stream, you have no chance (with direct FileInputStream use) to retrieve the underlying File or the location – Stephane Toussaint Mar 27 '15 at 16:48