我正在尝试运行程序来替换文件中的某些数据。尝试替换的文件的相关部分如下所示:
1 Information 15e+10
2 Information 2e+16
3 Information 6e+2
等等。
有问题的文件在数千兆字节范围内可能非常大,据我所知,因为使用整个文件的缓冲区并重写整个文件是不可能/不合理的。那很好,我只想替换值(例如15e+10
)。
如果我使用类似大小的值(ios::in|ios::out
- > tellp()
)替换值,或者即使它的值很小,这一切都可以使用简单的15e+10
和12e+12
。更小的尺寸,因为我可以简单地添加一个额外的空间,可以在线下忽略(例如15e+10
- > 4e+10
)。但是如果我需要用长度比文件中已有的值替换值(例如6e+2
- > 16e+10
),我会遇到问题,它会写入新行字符或开始写下一行中的信息。
我在论坛上搜索过,每个人都说你可以覆盖文件,你可以追加到文件的末尾,或者你可以缓冲并重新创建整个文件。无论如何,我可以实现我无需重新创建文件即可正确覆盖值的目标吗?
如果没有,那么如果有多个文件对于内存来说太大,我怎么能打开2个文件(1个输入1个输出)?
注意:我还想避免使用boost::
因为我需要能够在没有 boost 库的系统上运行它。
答案 0 :(得分:1)
打开要从输入(IN)文件读取的流和第二个流(OUT)以写入新输出(tmp)文件。
从IN读取并写入OUT。当您从IN获取要替换的值时,将替换写入OUT而不是从IN获得的值。
解析完成后,将第一个文件替换为第二个(tmp)文件。
这对你有用吗?
答案 1 :(得分:0)
使用lseek() / fseek()“跳转”到文件中的给定位置。
答案 2 :(得分: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 |
唯一副作用是文件大小与之前相同