1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <stack>
#include <string>
class ReverseReader
{
public:
ReverseReader(const std::string& fileName,int numberOfLines,int estimatedAvgLineLength=80)
: stream(fileName.c_str(),std::ios::ate|std::ios::binary), currentLine(0), cpos(-1), totalLines(numberOfLines),
avgLineLength(estimatedAvgLineLength), lastLinePos(0)
{
if (stream.tellg()==0)return;
try {while (currentLine<totalLines)readLine();}
catch (int) {}
printAllLines();
}
private:
void fillVector()
{
int blockSize=std::min(int((totalLines-currentLine)*avgLineLength*1.3),int(stream.tellg()));
if (blockSize<=0 || !stream.good())return;
stream.seekg(-blockSize,std::ios::cur);
buf.resize(lastLinePos);
buf.insert(buf.begin(),blockSize,0);
stream.read(&buf[0],blockSize);
stream.seekg(-blockSize,std::ios::cur);
cpos+=blockSize;
lastLinePos+=blockSize;
}
char peek()
{
if (cpos<0)fillVector();
if (cpos<0)throw int();
return buf[cpos];
}
char readChar()
{
char ch=peek();
cpos--;
return ch;
}
void readLine()
{
try {while (readChar()!='\n');}
catch(int)
{
if (lastLinePos-cpos-1)output(std::string(&buf[cpos+1],lastLinePos-cpos-1));
throw;
}
output(std::string(&buf[cpos+2],lastLinePos-cpos-2));
while (peek()=='\r')readChar();
currentLine++;
lastLinePos=cpos+1;
}
void output(const std::string& str)
{
if (currentLine==0 && str.empty())currentLine--;
else lines.push(str);
}
void printAllLines()
{
while (lines.size()>0)std::cout << lines.top() << std::endl,lines.pop();
}
std::ifstream stream;
int currentLine;
int cpos;
int totalLines;
int avgLineLength;
std::vector<char> buf;
std::stack<std::string> lines;
int lastLinePos;
};
int main(int argc,char** argv)
{
if (argc<2)return 1;
int n=argc>=3 ? atoi(argv[2]) : 0;
if (n==0)n=10;
ReverseReader reader(argv[1],n);
}
|