Why was the way to load files made the way it is in C++?

Started by
13 comments, last by MaulingMonkey 17 years, 10 months ago
If you want to read or write a file with C++, what most people probably want is functionality like string or vector = loadFile("filename.txt"), writeFile(string or vector, "filename.txt"), appendToFile(string or vector, "filename.txt") and getFileSize("filename.txt"). Why doesn't the C++ standard define functions like that, instead of the clumsy thing they now have with weird class names, unintuitive way to get the size of the file, ...? Or at least added something like this on top of the other system? I see no argument against more intuitive ways to get such things done.
Advertisement
Quote:Original post by Lode
If you want to read or write a file with C++, what most people probably want is functionality like string or vector = loadFile("filename.txt"), writeFile(string or vector, "filename.txt"), appendToFile(string or vector, "filename.txt") and getFileSize("filename.txt").

Why doesn't the C++ standard define functions like that, instead of the clumsy thing they now have with weird class names, unintuitive way to get the size of the file, ...? Or at least added something like this on top of the other system? I see no argument against more intuitive ways to get such things done.


Not everyone is using text files... How would that work with binary saved files? Or how would you make a binary file in the first place?

EDIT: Wrong word [embarrass]
  std::ifstream ifs("listofnumbers.txt");  std::vector<int> numbers( (std::istream_iterator<int>(ifs)),                            (std::istream_iterator<int>()));

If you want to create a wrapper function to give it an intuitive name, then go right ahead.
std::vector<T> vector = loadFile("filename.txt") would never work without passing lots of policies to the loadFile. How should a string be converted to T? What defines the end of an element? How is errors handled? etc. We already have something like writeFile, it's called operator<< and is used because it fits with the rest of the iostream library. If you had a writeFile function you wouldn't be able to properly do polymorphism. We don't write a vector because how should it be written? What about a string? Should it be 0-terminated or should it store its own length? zero termination could lead to problems when reading files and prefixing the length of the string could lead to readability errors. If you want functionality like this you could do this (this is just to show the idea, and it contains lots of errors):
template<class T>class writeable_vector : public vector<T>{public:  friend std::ostream& operator<<(std::ostream& stream,const writeable_vector<T>& out)  {    if( this->empty() )      return stream;    for( std::vector<T>::const_iterator iter = out.begin();      iter != (out.end()-1);      ++iter )    {      stream << iter << ", ";    }    stream << iter;  }};


We don't need appendToFile either, we just use operator<< to a file which we append to. Also we don't have getFileSize because C++ doesn't have a way to get info about the file system, which is needed, it only has the ability to open and close files, and read and write to them.

I don't think your methods is any more intuitive.
Quote:Original post by Lode
If you want to read or write a file with C++, what most people probably want is functionality like string or vector = loadFile("filename.txt"), writeFile(string or vector, "filename.txt"), appendToFile(string or vector, "filename.txt") and getFileSize("filename.txt").

Why doesn't the C++ standard define functions like that, instead of the clumsy thing they now have with weird class names, unintuitive way to get the size of the file, ...? Or at least added something like this on top of the other system? I see no argument against more intuitive ways to get such things done.


You are probably new to C++ and don't seem to realize that there's a whole number of different ways to deal with the corresponding data, so a uniform way isn't necessarily ideally suited or even appropriate to be used in the first place.
However, if you are mainly interested in doing generic file I/O without wanting to spend too much time making up file formats and I/O policies, you should probably check out the various existing serialization libraries for C++ (i.e. in boost). Depending on the scope of your problem, dumping an arbitrary object to a file can be extremely simple an unverbose. Likewise, reading data from files into objects back again, can usually also be done pretty quickly.




Quote:Original post by Anonymous Poster
You are probably new to C++ and don't seem to realize that there's a whole number of different ways to deal with the corresponding data, so a uniform way isn't necessarily ideally suited or even appropriate to be used in the first place.
However, if you are mainly interested in doing generic file I/O without wanting to spend too much time making up file formats and I/O policies, you should probably check out the various existing serialization libraries for C++ (i.e. in boost). Depending on the scope of your problem, dumping an arbitrary object to a file can be extremely simple an unverbose. Likewise, reading data from files into objects back again, can usually also be done pretty quickly.



Actually I'm really not new to C++ (well, I don't know if using it 4 years is considered new or not). I just have always avoided weird data types. To me a file is BYTES, so I use either std::strings or std::vectors<unsigned char> to represent files, and immediatly made wrappers with the names above for it (and some extra functions to turn an int/float/... into 2/4/8/... bytes added to the end of the string or vector and vica versa), so that I never had to look back at the original C++ way and am using "loadFile" and such since the beginning I started to use C++.

I'd never trust something that somehow places ints instead of bytes into a file by itself.

So whenever I see the standard C++ way I still find it weird, and finally I had to make a post about it.
string[] lines = File.ReadAllLines("file.txt");

Oh, C++...
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
In that case, your problem is that the C++ standards committee doesn't believe in promoting inefficient or otherwise inappropriate programming techniques. There's no single function to read a file into a string or std::vector<char> for much the same reason that there's no push_front() member function for std::vector<>: it would be making it too easy to do something that is largely inefficient. Reading the entire file as bytes into a byte oriented container like std::vector<char> would involve multiple copies of the same data into immediate subsequent buffers. C++ file stream I/O interfaces are built around the concept that the file stream itself will handle the buffering and that the user will extract the data as needed.
Quote:Original post by SiCrane
In that case, your problem is that the C++ standards committee doesn't believe in promoting inefficient or otherwise inappropriate programming techniques.

Let me offer the opinion that the C++ standards committee is a bunch of nitwits who will be the first against the wall when the revolution comes.

--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Quote:Original post by SiCrane
In that case, your problem is that the C++ standards committee doesn't believe in promoting inefficient or otherwise inappropriate programming techniques. There's no single function to read a file into a string or std::vector<char> for much the same reason that there's no push_front() member function for std::vector<>: it would be making it too easy to do something that is largely inefficient. Reading the entire file as bytes into a byte oriented container like std::vector<char> would involve multiple copies of the same data into immediate subsequent buffers. C++ file stream I/O interfaces are built around the concept that the file stream itself will handle the buffering and that the user will extract the data as needed.


I resize the std::vector to the size of the file first. Then I fill in the bytes one by one, using []. I think the problem of constant copying you mentioned doesn't happen then, right?

This topic is closed to new replies.

Advertisement