C ++逐个读取大文件

时间:2015-06-03 11:10:02

标签: c++

我一直遇到一个我迄今无法解决的问题。这个问题与阅读文件有关,我甚至在这个网站上查看了线程,他们似乎没有解决问题。该问题是读取大于计算机系统内存的文件。就在我刚才提出这个问题的时候,我也被引用了以下代码。

    string data("");
getline(cin,data);
std::ifstream is (data);//, std::ifstream::binary);
if (is) 
{
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);
    // allocate memory:
    char * buffer = new char [length];
    // read data as a block:
    is.read (buffer,length);
    is.close();
    // print content:

    std::cout.write (buffer,length);
    delete[] buffer;
}
system("pause");

这个代码除了在糖果店里像胖孩子一样吃记忆这个事实之外还有效。 因此,在经过大量的贫民窟和未精制的编程之后,我能够想出一种解决问题的方法。但是,在我的任务中,我或多或少地将另一个问题换成了另一个问题。

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <stdio.h> 
#include <stdlib.h>
#include <iomanip>
#include <windows.h>
#include <cstdlib>
#include <thread>

using namespace std;
/*======================================================*/
    string *fileName = new string("tldr");
    char data[36];
    int filePos(0); // The pos of the file
    int tmSize(0); // The total size of the file    

    int split(32);
    char buff;
    int DNum(0);
/*======================================================*/



int getFileSize(std::string filename) // path to file
{
    FILE *p_file = NULL;
    p_file = fopen(filename.c_str(),"rb");
    fseek(p_file,0,SEEK_END);
    int size = ftell(p_file);
    fclose(p_file);
    return size;
}

void fs()
{
    tmSize = getFileSize(*fileName);
    int AX(0);
    ifstream fileIn;
    fileIn.open(*fileName, ios::in | ios::binary);
    int n1,n2,n3;
    n1 = tmSize / 32;

    // Does the processing
    while(filePos != tmSize)
    {
        fileIn.seekg(filePos,ios_base::beg);
        buff = fileIn.get();
        // To take into account small files
        if(tmSize < 32)
        {
            int Count(0);
            char MT[40];
            if(Count != tmSize)
            {
                MT[Count] = buff;
                cout << MT[Count];// << endl;
                Count++;
            }
        }
        // Anything larger than 32
        else
        {
            if(AX != split)
            {
                data[AX] = buff;
                AX++;
                if(AX == split)
                {

                    AX = 0;
                }
            }

        }
        filePos++;
    }
    int tz(0);
    filePos = filePos - 12;

    while(tz != 2)
    {
        fileIn.seekg(filePos,ios_base::beg);
        buff = fileIn.get();
        data[tz] = buff;
        tz++;
        filePos++;
    }

    fileIn.close();
}

void main ()
{
    fs();
    cout << tmSize << endl;
    system("pause");
}

我尝试使用此代码的方法是解决内存问题。我没有为我的系统上根本不存在的大文件分配内存,而是尝试使用我所拥有的内存,而不是大约8GB,但我只想尽可能使用几千字节的内存。 为了给你一个我正在谈论的内容的布局,我将写一行文字。 “你好,我的名字是蛋糕,请给我蛋糕” 基本上我所做的就是逐字逐句地阅读这段文字。然后我将这些字母放入一个可以存储其中32个的框中,从那里我可以使用类似xor的东西,然后将它们写入另一个文件。 这种想法在某种程度上有效,但速度非常慢,而且不会丢失部分文件。 所以基本上我怎么能做这样的工作而不会减慢或切断文件。我很想看看xor如何处理非常大的文件。 所以,如果有人比我有更好的想法,那么我将非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

要逐个阅读和处理文件,您可以使用以下代码段:

// Buffer size 1 Megabyte (or any number you like)
size_t buffer_size = 1<<20;
char *buffer = new char[buffer_size];

std::ifstream fin("input.dat");

while (fin)
{
    // Try to read next chunk of data
    fin.read(buffer, buffer_size);
    // Get the number of bytes actually read
    size_t count = fin.gcount();
    // If nothing has been read, break
    if (!count) 
        break;
    // Do whatever you need with first count bytes in the buffer
    // ...
}

delete[] buffer;

正如您所使用的,32字节的缓冲区大小肯定太小。你对库函数进行了太多的调用(反过来,库会对OS进行调用(尽管可能不是每次),这通常很慢,因为它们会导致上下文切换)。也没有必要告诉/寻求。

答案 1 :(得分:0)

如果您不同时需要所有文件内容,请首先减少工作集 - 就像一组约32个字一样,但由于XOR可以按顺序应用,您可以进一步简化具有恒定大小的工作集,像4千字节。

现在,您可以选择在循环中使用文件阅读器is.read()并在每次迭代时处理一小组数据,或使用memmap()将文件内容映射为您可以执行的内存指针读写操作。