Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to read binary file c++ though input redirection

I am trying to read a large binary file thought input redirection (stdin) at runtime, and stdin is mandatory.

./a.out < input.bin

So far I have used fgets. But fgets skips blanks and newline. I want to include both. My currentBuffersize could dynamically vary.

FILE * inputFileStream = stdin; 
int currentPos = INIT_BUFFER_SIZE;
int currentBufferSize = 24; // opt
unsigned short int count = 0; // As Max number of packets 30,000/65,536
while (!feof(inputFileStream)) {
    char buf[INIT_BUFFER_SIZE]; // size of byte
    fgets(buf, sizeof(buf), inputFileStream);
    cout<<buf;
    cout<<endl;
}

Thanks in advance.

like image 279
Jerry Avatar asked Sep 28 '16 20:09

Jerry


1 Answers

If it were me I would probably do something similar to this:

const std::size_t INIT_BUFFER_SIZE = 1024;

int main()
{
    try
    {
        // on some systems you may need to reopen stdin in binary mode
        // this is supposed to be reasonably portable
        std::freopen(nullptr, "rb", stdin);

        if(std::ferror(stdin))
            throw std::runtime_error(std::strerror(errno));

        std::size_t len;
        std::array<char, INIT_BUFFER_SIZE> buf;

        // somewhere to store the data
        std::vector<char> input;

        // use std::fread and remember to only use as many bytes as are returned
        // according to len
        while((len = std::fread(buf.data(), sizeof(buf[0]), buf.size(), stdin)) > 0)
        {
            // whoopsie
            if(std::ferror(stdin) && !std::feof(stdin))
                throw std::runtime_error(std::strerror(errno));

            // use {buf.data(), buf.data() + len} here
            input.insert(input.end(), buf.data(), buf.data() + len); // append to vector
        }

        // use input vector here
    }
    catch(std::exception const& e)
    {
        std::cerr << e.what() << '\n';
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Note you may need to re-open stdin in binary mode not sure how portable that is but various documentation suggests is reasonably well supported across systems.

like image 119
Galik Avatar answered Nov 14 '22 07:11

Galik