3

I want to copy one image file to another new file. This is my method to do this:

    std::ofstream myOutpue;
    std::ifstream mySource;
    //int i = 0;
    mySource.open(ofn.lpstrFile, std::ios::binary);
    myOutpue.open("im4.jpg", std::ios::binary);
    char buffer;
    char bufferToSave[100];
    if (mySource.is_open())
    {
        //client->sendFilePacket(FileStates::START_SAVE, buffer, false,i);
        i++;
        while (!mySource.eof())
        {
            mySource >> std::noskipws >> buffer;
            myOutpue << buffer;
            //client->sendFilePacket(FileStates::CONTINUE_SAVE, buffer, false,i);
            i++;
        }
    }
    i++;
    //client->sendFilePacket(FileStates::END_SAVE, buffer, true,i);
    mySource.close();
    //myOutpue.close();

This method work correctly, but my problem is that i want to copy char/bit's and send it to another client. When i doing this by each char , that not work correctly so i want to make a bigger buffor(for example char t[512]) or something like that and copy them to new file.

I try to doing this like that:

    std::ofstream myOutpue;
    std::ifstream mySource;
    mySource.open(ofn.lpstrFile, std::ios::binary);
    myOutpue.open("im4.jpg", std::ios::binary);
    char buffer;
    char bufferToSave[100];
    if (mySource.is_open())
    {
        //client->sendFilePacket(FileStates::START_SAVE, buffer, false,i);
        i++;
        while (!mySource.eof())
        {
            if (i == 100)
            {
                for (int i = 0; i < 100; i++)myOutpue << bufferToSave[i];
                i = 0;
            }
            mySource >> std::noskipws >> buffer;
            bufferToSave[i] = buffer;
            //myOutpue << buffer;
            //client->sendFilePacket(FileStates::CONTINUE_SAVE, buffer, false,i);
            i++;
        }
    }
    i++;
    //client->sendFilePacket(FileStates::END_SAVE, buffer, true,i);
    mySource.close();
    myOutpue.close();

But i get image that i can't open.

So my question is how to read file to get more bits from it and that create me the same image as original.

dawcza94
  • 327
  • 2
  • 10
  • This: `while (!mySource.eof())` is potentially corrupting your files: https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – Galik Feb 24 '16 at 16:52
  • What are the parameters for `sendFilePacket()`? – Galik Feb 24 '16 at 17:01

5 Answers5

2

You have an error in your original file copy algorithm in that you should never loop using eof() as the end flag.

See: Why is iostream::eof inside a loop condition considered wrong?

Copying files can be a simple as this:

    std::ofstream("output.jpg", std::ios::binary) << std::ifstream("input.jpg", std::ios::binary).rdbuf();

It uses a special overload of the output operator when passing an std::istream buffer (using rdbuf()). It copies the whole stream.

When reading a whole buffer you should use std::istream::read:

    std::ifstream ifs("input.jpg", std::ios::binary)

    char buffer[1025]; // create a buffer

    // keep going as long as the reading succeeds
    while(ifs.read(buffer, sizeof(buffer)))
    {
        // ifs.gcount() is the number of chars read successfully
        client->sendFilePacket(buffer, ifs.gcount()); // send all bytes
    }
Galik
  • 47,303
  • 4
  • 80
  • 117
1

I know it's been a long time, but reading these topic I found the solution:

    std::ifstream ifs(ofn.lpstrFile, std::ios::binary);
    std::ofstream myOutpue;
    char buffer[1024]; // create a buffer
    myOutpue.open("output.jpg", std::ios::binary);
    //client->sendFilePacket(FileStates::START_SAVE, buffer, false, i);
    while (ifs.read(buffer, sizeof(buffer)))
    {
        myOutpue.write(buffer, ifs.gcount());
    }
    //
    myOutpue.write(buffer, ifs.gcount());
    myOutpue.close();

Note: My answer is similar to @dawcza94, but to avoid black screen, after the loop you have to save the rest of the reading, because in the loop you save only what fits in the buffer, and the rest you ignore. Sometimes it happens that the rest can be a few characters long, and it looks like the images are the same size, but they aren't.

Note2: I posted here to help those who are still in trouble as I was!!

0

C++ FAQ:

You probably want to use iostream’s read() and write() methods instead of its >> and << operators. read() and write() are better for binary mode; >> and << are better for text mode.

You can specify how much you want to read. With gcount you can ask, how much characters are read successfully. Same goes for write.

knivil
  • 787
  • 3
  • 11
  • Solves part of the problem, but you want to detail this and fill it out a bit more to go from correct comment to correct answer. – user4581301 Feb 24 '16 at 18:44
0

I try with this code:

    std::ifstream ifs(ofn.lpstrFile, std::ios::binary);
    std::ofstream myOutpue;
    char buffer[1024]; // create a buffer
    myOutpue.open("output.jpg", std::ios::binary);
    //client->sendFilePacket(FileStates::START_SAVE, buffer, false, i);
    while (ifs.read(buffer, sizeof(buffer)))
    {
        //client->sendFilePacket(FileStates::CONTINUE_SAVE, buffer, false, ifs.gcount());
        myOutpue.write(buffer, ifs.gcount());
    }
    //client->sendFilePacket(FileStates::END_SAVE, buffer, true, i);
    myOutpue.close();

But when i doing this like that, in my copy of image i got only half of original image and half of black screen( number of kb is the same like in original file), so i don't know what's a problem with that ?

dawcza94
  • 327
  • 2
  • 10
-1

Instead of using "manual" copy, try using ifstream::read method

norisknofun
  • 859
  • 1
  • 8
  • 24