0

我正在尝试运行一个程序来替换文件中的某些数据。试图被替换的文件的相关部分如下所示:

1 Information 15e+10

2 Information 2e+16

3 Information 6e+2

等等。

有问题的文件在数 GB 范围内可能非常大,据我了解,因为使用整个文件的缓冲区并重写整个文件是不可能/不合理的。好吧,我只想替换值(例如15e+10)。

这一切都适用于简单ios::in|ios::outtellp()如果我用类似大小的值(15e+10-> 12e+12)替换该值,或者即使它的大小更小,因为我可以简单地添加一个额外的空间,可以在一行中忽略(例如15e+10-> 4e+10 ) . 但是,如果我需要用一个长度比文件中已经存在的值(例如6e+2-> 16e+10)更长的值替换该值,我就会遇到问题,它将覆盖换行符或开始覆盖下一行中的信息.

我在论坛上搜索过,每个人都说您可以覆盖文件,可以附加到文件末尾,也可以缓冲并重新创建整个文件。无论如何我可以实现正确覆盖值而无需重新创建文件的目标吗?

如果没有,那么如果有问题的多个文件对于内存来说太大了,我怎么能打开 2 个文件(1 个输入 1 个输出)来执行此操作?

注意:我也想避免使用boost::,因为我需要能够在没有boost库的系统上运行它。

4

3 回答 3

1

打开一个流以从输入 (IN) 文件中读取,并打开第二个流 (OUT) 以写入新的输出 (tmp) 文件。

从 IN 读取并写入 OUT。当您从 IN 获得要替换的值时,将替换写入 OUT 而不是从 IN 获得的值。

解析完成后,将第一个文件替换为第二个 (tmp) 文件。

这对你有用吗?

于 2013-10-08T14:04:53.533 回答
0

使用lseek() /fseek() “跳转”到文件中的给定位置。

于 2013-10-08T14:07:03.780 回答
0

您可以使用seekp转到该位置并使用<<

例子:

example.txt (|?| = 1 字节数据)

|A|B|C|\n|1|2|3|D|E|F|\n|4|5|6|

//Somewhere in the code

fstream file;

open("example.txt");

//Somehow find the character distance and store it into "distance"

seekp(distance);//If distance = 0, it will go to "A" like rewind() but easier for me

如果距离为 4,下一个字符将被覆盖为1

file << "987";

该文件将是

|A|B|C|\n| 9 | 8 | 7 |D|E|F|\n|4|5|6|

这里唯一的问题是当您需要增加/减少大小时:

增加:

您将覆盖另一个字符,因此您需要创建一个临时字符串来存储其余数据,或者如果数据太大,则将其分成较小的块,例如

|A|B|C|\n| 9 | 8 | 7 |D|E|F|\n|4|5|6|

string tempstring;
seekp(distance);
file >> tempstring;
seekp(distance);
file << content << tempstring;  //content is the data

减少:

最简单的解决方案是将NULL 字符 \0写入多余的空间,例如

|A|B|C|\n| 1 | \0 | \0 |D|E|F|\n|4|5|6|

唯一的副作用是文件大小与以前相同

于 2017-09-17T18:07:04.937 回答