61

Can I get a file name or its path from a fstream object? I looked through the methods of fstream and didn't find anything close to it.

Nan Xiao
  • 16,671
  • 18
  • 103
  • 164
Pavel Oganesyan
  • 6,774
  • 4
  • 46
  • 84
  • 8
    I don't think that's possible. The underlying file may have several names (if it has multiple hard links) or no name at all (if it represents an anonymous pipe, for instance). – Frédéric Hamidi May 27 '12 at 10:59

2 Answers2

55

No, that is not possible, not at least in the Standard conformant implementation of the library.

The fstream class doesn't store the filename, and doesn't provide any function for retrieving it.

So one way to keep track of this information is to use std::map as:

std::map<std::fstream*, std::string> stream_file_table;

void f()
{
  //when you open a file, do this:
  std::fstream file("somefile.txt");

  stream_file_table[&file] = "somefile.txt"; //store the filename

  //..
  g(file);
}
void g(std::fstream & file)
{
    std::string filename = stream_file_table[&file]; //get the filename
    //...
}

Or, simply pass around the filename as well.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    This looks alright, only you would need to say that the name has to be removed once the fstream objects get destroyed... – Alexis Wilke Jun 01 '16 at 03:10
  • 1
    It is perfectly possible to be standard conformat *and* include a way to retrieve the filename used to open a file. That's called an extension. – Clearer Aug 15 '19 at 07:28
  • 1
    @Clearer No-one said it'd be non-conforming then. The point is the Standard does not provide for it. – bloody Jan 07 '21 at 09:27
  • @bloody It says "not at least in the Standard conformant implementation" which makes it sound like having that feature would make it non conforming – Jimmy T. Jul 20 '21 at 08:45
  • 1
    Extensions are NOT part of the Standard. If you use such features, then your code is NOT standard conformant anymore. If you change your compiler, then your code may not compile as your new compiler might be missing the extension you're using in your code. – Nawaz Jul 25 '21 at 06:07
31

you may also design a little class which inherits from fstream and behaves like a fstream but also stores its file name.

Walter
  • 44,150
  • 20
  • 113
  • 196
  • 8
    This also allows you to add a convenient constructor taking a `std::string`, which is required in C++11 but not usually present in C++03 implementations. – Jonathan Wakely May 27 '12 at 13:12
  • Or if reusability and/or extendability is of no concern, a simple struct storing a string and a file stream object. – Smartskaft2 Jun 27 '21 at 05:34