我正在尝试向这篇文章提出类似的问题: C: read binary file to memory, alter buffer, write buffer to file 但答案对我没有帮助(我是c ++的新手所以我无法理解所有这些)
如何循环访问内存中的数据,并逐行浏览,以便我可以将其写入不同格式的文件中?
这就是我所拥有的:
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main()
{
char* buffer;
char linearray[250];
int lineposition;
double filesize;
string linedata;
string a;
//obtain the file
FILE *inputfile;
inputfile = fopen("S050508-v3.txt", "r");
//find the filesize
fseek(inputfile, 0, SEEK_END);
filesize = ftell(inputfile);
rewind(inputfile);
//load the file into memory
buffer = (char*) malloc (sizeof(char)*filesize); //allocate mem
fread (buffer,filesize,1,inputfile); //read the file to the memory
fclose(inputfile);
//Check to see if file is correct in Memory
cout.write(buffer,filesize);
free(buffer);
}
我感谢任何帮助!
修改(有关数据的更多信息):
我的数据是5到10GB之间不同的文件。大约有3亿行数据。每一行看起来像
M359
T359 3520 359
M400
A3592 zng 392
第一个元素是字符,其余项目可以是数字或字符。我正在尝试将其读入内存,因为逐行循环比读取行,处理然后写入要快得多。我在64位linux编译。如果我需要进一步澄清,请告诉我。再次谢谢你。
编辑2 我使用switch语句来处理每一行,其中每行的第一个字符确定如何格式化该行的其余部分。例如,'M'表示毫秒,我将接下来的三个数字放入一个结构中。每一行都有不同的第一个字符,我需要做一些不同的事情。
答案 0 :(得分:2)
所以原谅可能明显的明显,但如果你想逐行处理,那么......
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
// read lines one at a time
ifstream inf("S050508-v3.txt");
string line;
while (getline(inf, line))
{
// ... process line ...
}
inf.close();
return 0;
}
然后填写while循环的主体?也许我没有看到真正的问题(树木的森林有点像)。
编辑
OP与使用自定义streambuf一致,这可能不一定是世界上最便携的东西,但他更有兴趣避免在输入和输出文件之间翻转。有足够的RAM,这应该可以解决问题。
#include <iostream>
#include <fstream>
#include <iterator>
#include <memory>
using namespace std;
struct membuf : public std::streambuf
{
membuf(size_t len)
: streambuf()
, len(len)
, src(new char[ len ] )
{
setg(src.get(), src.get(), src.get() + len);
}
// direct buffer access for file load.
char * get() { return src.get(); };
size_t size() const { return len; };
private:
std::unique_ptr<char> src;
size_t len;
};
int main(int argc, char *argv[])
{
// open file in binary, retrieve length-by-end-seek
ifstream inf(argv[1], ios::in|ios::binary);
inf.seekg(0,inf.end);
size_t len = inf.tellg();
inf.seekg(0, inf.beg);
// allocate a steam buffer with an internal block
// large enough to hold the entire file.
membuf mb(len+1);
// use our membuf buffer for our file read-op.
inf.read(mb.get(), len);
mb.get()[len] = 0;
// use iss for your nefarious purposes
std::istream iss(&mb);
std::string s;
while (iss >> s)
cout << s << endl;
return EXIT_SUCCESS;
}
答案 1 :(得分:0)
如果我必须这样做,我可能会使用类似这样的代码:
std::ifstream in("S050508-v3.txt");
std::istringstream buffer;
buffer << in.rdbuf();
std::string data = buffer.str();
if (check_for_good_data(data))
std::cout << data;
这假设您确实需要一次在内存中输入文件的全部内容,以确定是否应将其复制到输出。如果(例如)你可以一次查看一个字节的数据,并确定是否应该复制该字节而不查看其他字节,你可以做更多的事情:
std::ifstream in(...);
std::copy_if(std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>(),
std::ostream_iterator<char>(std::cout, ""),
is_good_char);
...其中is_good_char
是一个返回bool
的函数,说明是否应将char
包含在输出中。
编辑:您正在处理的文件大小主要是排除了我上面给出的第一种可能性。你也是正确的,读取和写入大块数据几乎肯定会提高一次在一行上工作的速度。
答案 2 :(得分:0)
你应该研究fgets和scanf,你可以在其中提取匹配的数据片段,以便更容易操作,假设这是你想要做的。这样的事情看起来像:
FILE *input = fopen("file.txt", "r");
FILE *output = fopen("out.txt","w");
int bufferSize = 64;
char buffer[bufferSize];
while(fgets(buffer,bufferSize,input) != EOF){
char data[16];
sscanf(buffer,"regex",data);
//manipulate data
fprintf(output,"%s",data);
}
fclose(output);
fclose(input);
这将是C语言的更多方式,C ++通过使用istream更有说服力地处理事情: http://www.cplusplus.com/reference/istream/istream/