Can Not Open File in Loop C++ - c++

I have a c++ application which have the following code:
for (int i = 0; i < ALL_EPID_CERTS_LENGTH; i++)
{
std::ifstream file(;
file.open(path.append(ALL_EPID_CERTS_1_0[i]), std::ios::in | std::ios::binary);
if(file.is_open())
{
// get the length of the file
file.seekg(0, ios::end);
size_t fileSize = file.tellg();
file.seekg(0, ios::beg);
// create a vector to hold all the bytes in the file
vector<byte> data(fileSize, 0);
// read the file
file.read(reinterpret_cast<char*>(&data[0]), fileSize);
byte *tempCerts = new byte[data.size()+1];
memset(tempCerts,0,fileSize+1);
std::copy(data.begin(), data.begin()+(data.size()), tempCerts);
// !!!!check if NULL and place for NULL are needed
for (int j = 0; j < data.size(); j++)
{
list.push_back(tempCerts[j]);
}
file.close();
}
}
In the first iteration the loop does the expected, but since the second one - file.is_open() returns false.
All the files are existing.
Sould you explain me please what is wrong???

You do path.append - what is path? What do you expect it to be after first iteration - is it ok that ALL_EPID_CERTS_1_0[1] is appended to ALL_EPID_CERTS_1_0[0]?

You may need to call infile.clear(); to clear the state bits after closing the stream, otherwise you can't open a new file with the same stream.
Also: Are you sure you need to append to the path at every iteration? Output your path variable after every append call and check if the paths are correct. I expect that at the second iteration the path string will look something like this: "c:/some/path/file1.txtfile2.txt"
In cases like this I would use a stringstream or sprintf to generate the path, and make sure not to change the path variable.

Related

Stopping and Starting read / copy on binary file

So i'm attempting to copy a binary file up to a certain point...stop...perform some operations, then copy the remaining contents from the original binary out to my new binary. However when i perform my second read operation, my read buffer is empty. Can someone point out what I'm doing wrong here? Thanks so much...
ifstream fin;
fin.open(argv[1], ios::in | ios::binary);
ofstream fout("test.bin", ios::out | ios::binary);
int position = getPositionX();
fin.seekg(position);
streamoff initialCopyLength = fin.tellg();
char * readBuffer = new char[initialCopyLength];
fin.seekg(0, fin.beg);
fin.read(readBuffer, initialCopyLength);
fout.write(readBuffer, initialCopyLength);
///perform some operations, then copy out the rest of the binary
int currentPosition = fin.tellg();
fin.seekg(0, fin.end);
streamoff length = fin.tellg();
readBuffer = new char[length];
fin.read(readBuffer, length);
//write out last part of file
fout.write(readBuffer, length);
fin.close();
fout.close();
You seek to the end of the file with fin.seekg(0, fin.end); but you never seek back to the read position before you try to read() so you read nothing as you are at the end. You need another seekg call before you read() so you get back to where you were. Adding
fin.seekg(currentPosition, fin.beg);
will get you back to where you were.
You also have a mistake with
streamoff length = fin.tellg();
this is giving you the total file size. To get what is left you need
streamoff length = fin.tellg() - currentPosition;

C++ How To Copy Part of A Binary File To A New File?

I have a long binary file as an input to a function. I can copy all the data to a new file as follows:
void copyBinaryFile(string file){
const char* fileChar = file.c_str();
ifstream input(fileChar, ios::binary);
ofstream output("/home/my_name/result.img", ios::binary);
copy(istreambuf_iterator<char>(input),
istreambuf_iterator<char>(),
ostreambuf_iterator<char>(output)
);
}
This works fine for copying an entire file in one go, however, what I actually want to do is take several non-consecutive chunks of the first binary file and write them all to the output file, i.e.
for(int i = 0; i < chunkArray.size(); i++){
//copy 512 bytes from file1 to file2 starting at the chunkArray[i]th character
}
How would I do this? This is on Linux if it makes any difference.
Use ifstream::seekg to move the reading position of the file.
Read the appropriate number of bytes from the file.
Process the data read from the file.
Repeat until you are done.
for(int i = 0; i < chunkArray.size(); i++){
//copy 512 bytes from file1 to file2 starting at the chunkArray[i]th character
input.seekg(chunkArray[i]);
char chunk[512];
input.read(chunk, 512);
// Deal with error, if there is one.
if (!input )
{
}
// Process the data.
}
Seems simple enough..
Have your function take an offset into the source that it should start copying from, as well as a number of bytes to copy. Then copy that many bytes from the given starting point.

ifstream doesn't read to buffer

In the following code the read method doesn't seem to fill the given buffer:
ifstream pkcs7_file(file_name, std::ios::binary);
if ( pkcs7_file.fail() )
{
std::cout << "File failed before reading!\n";
}
pkcs7_file.seekg(0, pkcs7_file.end);
size_t len = pkcs7_file.tellg();
char * buffer = new char[len];
pkcs7_file.read(buffer, len);
pkcs7_file.close();
When debugging with VS 2012 and printing, the Len variable is as expected (and not zero) but the buffer doesn't change after the read function - it remains with the same value from before the read.
What am I doing wrong?
You seek to end-of-file, and then try to read. Of course it fails - the file is positioned at EOF, there's no data to read.

Split a File and put it back together in c++

I want to copy a file by reading blocks of data, sending it and than put it back together again. Sending is not part of the problem, so I left it out in the code. It should work with any type of file and arbitrary piece_lengths.
This is just a pre-stage. In the end data block should not be chosen sequentially but at random. There could be some time between receiving another block of data.
I know the example just makes sense if size % piece_length != 0.
I'm getting crashed files of the same size as the original file at the other end.
Does anyone see the problem?
int main ()
{
string file = "path/test.txt"
string file2 = "path2/test.txt";
std::ifstream infile (file.c_str() ,std::ifstream::binary);
//get size of file
infile.seekg (0,infile.end);
long size = infile.tellg();
infile.seekg (0);
size_t piece_length = 5;
for (int i = 0; i < ((size / piece_length) + 1); i++)
{
if ( i != (size / piece_length))
{
std::ifstream infile (file.c_str() ,std::ifstream::binary);
infile.seekg((i * piece_length) , infile.beg);
char* buffer = new char[piece_length];
infile.read(buffer, piece_length);
infile.close();
std::ofstream outfile (file2.c_str() ,std::ofstream::binary);
outfile.seekp((i * piece_length), outfile.beg);
outfile.write(buffer, piece_length);
outfile.close();
}
else
{
std::ifstream infile (file.c_str() ,std::ifstream::binary);
infile.seekg((i * piece_length) , infile.beg);
char* buffer = new char[size % piece_length];
infile.read(buffer, size % piece_length);
infile.close();
std::ofstream outfile (file2.c_str() ,std::ofstream::binary);
outfile.seekp((i * piece_length), outfile.beg);
outfile.write(buffer, size % piece_length);
outfile.close();
}
}
return 0;
}
To answer your specific question, you need to open outfile with ios::in | ios::out in the flags, otherwise it defaults to write-only mode and destroys what was already in the file. See this answer for more details: Write to the middle of an existing binary file c++
You may want to consider the following though:
If you are just writing parts to the end of the file, just use ios::app (append). Don't even need to seek.
You don't need to keep reopening infile or even outfile, just reuse them.
You can also reuse buffer. Please remember to delete them, or better yet use a std::vector.

C++: Everytime I read in by fstream I got 1 extra character at the end

Everytime I read in by fstream I got 1 extra character at the end, How can I avoid this?
EDIT:
ifstream readfile(inputFile);
ofstream writefile(outputFile);
char c;
while(!readfile.eof()){
readfile >> c;
//c = shiftChar(c, RIGHT, shift);
writefile << c;
}
readfile.close();
writefile.close();
This typically results from testing for the end of file incorrectly. You normally want to do something like:
while (infile>>variable) ...
or:
while (std::getline(infile, whatever)) ...
but NOT:
while (infile.good()) ...
or:
while (!infile.eof()) ...
The first two do a read, check whether it failed, and if so exit the loop. The latter two attempt a read, process what's now in the variable, and then exit the loop on the next iteration if the previous attempt failed. On the last iteration, what's in the variable after the failed read will normally be whatever was in it previously, so loops like either of the second two will typically appear to process the last item in the file twice.
To copy one file to another easily, consider using something like this:
// open the files:
ifstream readfile(inputFile);
ofstream writefile(outputFile);
// do the copy:
writefile << readfile.rdbuf();
This works well for small files, but can slow down substantially for a larger file. In such a case, you typically want to use a loop, reading from one file and writeing to the other. This also has possibilities for subtle errors as well. One way that's been tested and generally work reasonably well looks like this:
std::ifstream input(in_filename, std::ios::binary);
std::ofstream output(out_filename, std::ios::binary);
const size_t buffer_size = 512 * 1024;
char buffer[buffer_size];
std::size_t read_size;
while (input.read(buffer, buffer_size), (read_size = input.gcount()) > 0)
output.write(buffer, input.gcount());
Based on the code, it appears what you're trying to do is copy the contents of one file to another?
If so, I'd try something like this:
ifstream fin(inputFile, ios::binary);
fin.seekg(0, ios::end);
long fileSize = fin.tellg();
fin.seekg(0, ios::beg);
char *pBuff = new char[fileSize];
fin.read(pBuff, fileSize);
fin.close();
ofstream fout(outputFile, ios::binary)
fout.write(pBuff, fileSize);
fout.close;
delete [] pBuff;