I am having a hell of a time trying to open files on a network drive with ifstream.
I can successfully open the file if... I explicitly declare the filename, such as ifstream f("filename.txt").
However, that is the only way I can get the file open, and I need be able to dynamically find the name of that file and open it. Right now I have a string vector of the filenames in a given folder.
I have tried the following as input arguments to the ifstream constructor, to no success.
converting the string using c_str().
declaring a char* and assigning the string.cstr() to it.
same as above, but const char*
changed the system directory to the folder where the file is, and inputted the filename itself (relative path)
I print out the filename and change to its directory each time before trying to open it, so I know for a fact the filename is 100% correct.
Related
I'm having troubles with ofstream , which is - when I change value of ofstream object like this
ofstream o_save;
/*code*/
o_save = ofstream(filename); //Problem is here
...the line above completely erase contents of file.
The question is how do I legitimately change filename value of ofstream object ?
P.S. I cant define it when I declare it, because I want it global and I'm not sure which save file I select.
The question is quite vague and contradictory, and the OP seems to have slept after asking the question. So I shall try to peek inside his head and try to elaborate what he wants.
For opening a file, there are many modes for that. Open it like this.
ofstream o_value ;
o_value.open("file.txt") ;
If you want to preserve the original contents of that file, use..
o_value.open("file.txt", ios::app) ;
If you want to close it later and open another one, close using...
o_value.close() ;
Chaning of file names is normally not allowed in case of ofstream. You can use rename from <cstdlib>. You can delete a file though using remove("file.txt") in <cstdio> .
What does it mean to "change the name" of an ofstream object?
The only "name" an ofstream object has is the name of the
variable. An ofstream object is a data stream. You can (on
some systems) change the name of the file it is associated with,
using rename, but somehow, I don't think this is what you want
either. You can also close the stream, and reopen it on another
file.
You cannot assign between iostream objects. If worse comes to
worse, you can declare the global object as a pointer, and
assign to it (using *o_save to write to it).
Finally, the standard says that when you open an ofstream, you
truncate the file, if one exists. If this is not what you want
to do, then you have to add some flags to the open mode. If you
add std::ios_base::app, for example, you will no longer
truncate the file, and all writes will be to the end of file
(atomically, if the system supports it). Alternatively (albeit
quite surprising), you could add std::ios::in to the flags;
this will fail if the file doesn't exist, but will allow writing
anywhere in the file. This is the only way to open a file for
writing if you want to be able to write anywhere in the file,
even if you don't want to read it.
The ofstream does not have some kind of an abstract name attribute, the name is just a parameter to some of its member functions, in that sense asking how to
change filename value of ofstream object
is meaningless.
In general you can rename files with std::rename from <cstdlib> or use Boost.Filesystem.
I am developing in C++ using NetBeans 6.9 on Ubuntu 11.04. I have declared the input and output file name strings and file streams thus
ifstream fpInputFile, fpOutputFile;
string inputFileName="", outputFileName="";
The input file name is assigned the name of an existing file as an input argument to the application. The output file name is given the same as the input name except that "_output" is inserted before the final period. So the output is written to the same directory as the input is located. Also I start netbeans with
su netbeans
so the IDE has root privileges to the directory. I try to open the files, and check whether they are opened thus.
fpInputFile.open(inputFileName.c_str(), ifstream::in);
fpOutputFile.open(outputFileName.c_str(), ifstream::out);
if (!(fpInputFile.is_open())) throw ERROR_OPENING_FILE;
if (!(fpOutputFile.is_open())) throw ERROR_OPENING_FILE;
The input file opens successfully but the output file does not.
Any help in determining why the output file is not opening for writing would be most appreciated.
Declare the output file as an ofstream rather than a ifstream.
You could also use a fstream for both input and output files.
The obvious problem is that you probably meant to open the file using a std::ofstream rather than an std::ifstream. This helps with actually writing to the stream although there are ways to write to an std::ifstream as long as it is opened for reading. For example, you could use the std::streambuf interface directly or use the std::streambuf to construct and std::ostream.
The more interesting question is: why isn't the file opened for writing when std::ios_base::in | std::ios_base::out is used for the open mode? std::ifstream automatically adds std::ios_base::in. It turns out, that the mode std::ios_base::in | std::ios_base::out doesn't create a file but it would successfully open an existing file. If you really want use an std::ifstream to open a file for output which potentially doesn't exist you would need to use either std::ios_base::out | std::ios_base::trunc or std::ios_base::out | std::ios_base::app:
the former would force the file to be created or truncated if it exists
the latter would force writes to append to the file in all cases
My personal guess is, however, that you are best off just using std::ofstream or, if you want to open the file for both reading and writing std::fstream (which, however, would also need to have std::ios_base::trunc or std::ios_base::app added to create a file if none exists).
I am trying to create a temporary file in my C++ program by calling the tmpfnam function to get the temporary file name and using that to create the file for writing, but my code is unable to create the temporary file. However, file creation works absolutely fine when I use a user-supplied file name or a string constant instead of using a temporary name from tmpfnam. Here is an example :
std::tmpnam(fname); //does not work
std::fstream f(fname,std::ios::out);
char* fname = "myfile.txt"; //works
std::fstream f(fname,std::ios::out);
I checked that the file in case 2 is being created in the same directory as the source file, but not in case 1. I tried running the program under admin permissions as well and still no luck . Any idea why this is so ?
Have you tried it this way?
char fname[L_tmpnam];
if (std::tmpnam(fname)) {
std::fstream f(fname,std::ios::out);
// ...
}
Hope that it helps.
I am polling a directory constantly for files and every time I see a file that meets some certain criteria for reading, I open the file and parse it.
string newLine;
ifstream fileReader;
fileReader.open(filename.c_str());
while(!fileReader.eof())
{
getline(fileReader, newLine);
// do some stuff with the line...
}
filereader.close();
The above code is in a loop that runs every 1 second checking a directory for new files. My issue is that as I am transferring files into the folder for processing, my loop finds the file and passes the name of the file to ifstream who then opens it and tries to parse an incomplete file. How do I make ifstream wait until the file is done being written before it tries to parse the file?
EDIT:
Wanted to better word the issue here since a replier seems to have misunderstood my issue. I have 2 directories
mydirectory/
mydirectoryParsed/
THe way my code works is that my program checks for files in mydirectory/ and when it finds them, parses them and uses the information in the files. No writing to the files are done. Once I am done parsing the file, the file is moved to mydirectoryparsed/
The issue is that when I transfer files over the network into mydirectory/ the ifstream sees these files midtransfer and starts reading them before they finish writing to the directory. How do I make ifstream wait until the file is completely written before parsing it?
Don't transfer the files directly into the directory that your program is watching; instead, transfer them into a different directory on the same drive, and then when the transfer is done, move them into the watched directory. That way, the complete file appears in the watched directory in a single atomic operation.
Alternatively, you could use a naming convention in the watched directory — append a suffix like ".partial" to files that are being transferred, and then rename the file to remove the suffix when the transfer is done. Have your program ignore files whose names end with the suffix.
You're not supposed to open the file every time you write in it. Open it once!
Some pseudo-code for this would be :
1- Open file
2- Get the data you want to write, treat that data
3- Call the write to file function
4- Loop until you have nothing left to write
5- Close de file
I am just trying to open this file and use the getline function to read from the file but I cant seem to figure out why it is not working. I have stepped through it many times and the fileOpen variable is being loaded correctly with the file im trying to open, so Im unsure on why it wont open, to use getline with it. I would just like to be able to read through the file with getline, all of this is done in a recursive function to eventually read through all the files in directories. Let me know if you need more information on what exactly im doing.
string line;
ifstream file;
string fileOpen;
bf::directory_iterator dirIter ( fullPath ); //fullPath is type bf::path, passed into the function
fileOpen = (dirIter->path().filename());
file.open(fileOpen);
getline(file, line);
The path::filename function returns the base filename. If you have a path of "foo\bar.txt", path::filename will return "bar.txt". So unless "foo\" is in the current directory, the file probably doesn't exist.
What you're more likely looking for is this:
file.open(dirIter->path().native());
Or, you can use the boost::filesystem iostream types:
#include <boost/filesystem/fstream>
bf::ifstream file;
bf::directory_iterator dirIter ( fullPath ); //fullPath is type bf::path, passed into the function
file.open(dirIter->path());