0

I am trying to write a function which reads bytes backwards from a file. I know exactly how it should work but since I just started programming in C++ I have no idea how to do that.

Lets say that I have a 2 GB large file and I want to allocate last 800 MBs into the system memory (backwards). I would like it to be efficient; not loading the whole file since I won’t be needing 1.2 GBs of it.

So far with my limited knowledge I was able to write this but I am stuck right now. Certainly there must much more elegant way how to do that.

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

int main () {
    // open the file
    ifstream file;
    file.open(filename, ios_base::binary);

    //check for successful opening
    if(!file.is_open()){
        cout << "Error." << endl;
        exit(EXIT_FAILURE);
    }

    //get the lenght of a file
    file.seekg (0, file.end);
    long length = file.tellg();
    file.seekg (0, file.beg);

    //read given amount of bytes from back and allocate them to memory
    for (long i=0; i<=bytes_to_read-1; i++) {
        file.seekg(-i, ios::end);
        file.get(c);

        //allocation process

    }
    return 0;
} 
robert
  • 17
  • 7
  • 2
    Why don't you just `file.seekg(-bytes_to_read, ios::end)` first, read the `bytes_to_read` bytes, and call it a day? If you want to reverse the order of bytes, reverse them after you read them. – Sam Varshavchik Oct 13 '16 at 23:37
  • 1
    What @SamVarshavchik said. Seeking for each byte read is extreme inefficiency. It's something Windows Update could do. – Cheers and hth. - Alf Oct 13 '16 at 23:38
  • I thought that there might be a way how to do that without doing that extra step (reversing it in memory). I was able to load all the bytes into reference char array but since there is only reverse function for strings do you think I should implement my own? Is there a way around? – robert Oct 14 '16 at 00:30

2 Answers2

0

Use fseek to get where you want, and read the file from there. fp is a file pointer here.

fseek(fp, -10, SEEK_END); // seek to the 10th byte before the end of file

from http://beej.us/guide/bgc/output/html/multipage/fseek.html, or seekg if using iostream in C++.

Jack Ryan
  • 1,287
  • 12
  • 26
0

First there is a bug - you need to seek to -i-1 in the loop.

Secondly it's better to avoid so many system calls. Instead of reading byte by byte, read full buffer or some reasonable size and then reverse the buffer in memory.

Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43