我有一个正在写入的文本文件,作为非常大的数据提取的一部分。文本文件的第一行是提取的“帐户”数。
由于此提取的性质,该数字直到流程结束才知道,但文件可能很大(几百兆)。
C#/ .NET中打开文件的最佳方式是什么(在本例中是一个简单的文本文件),并替换文本第一行“数据”中的数据?
重要提示: - 我不需要替换“固定数量的字节” - 这很容易。这里的问题是需要插入文件顶部的数据是可变的。
重要说明2 : - 有些人询问/提到只是将数据保存在内存中然后替换它......但这完全是不可能的。这个过程正在更新的原因是因为有时它会在将几个演出装入内存时崩溃。
答案 0 :(得分:4)
如果可以的话,你应该插入一个占位符,你在最后用实际的数字和空格覆盖。
如果这不是一个选项,请先将数据写入缓存文件。当您知道实际数字时,请创建输出文件并附加缓存中的数据。
答案 1 :(得分:3)
BEST非常主观。对于任何小文件,您可以轻松地在内存中打开整个文件,并使用字符串替换替换您想要的内容,然后重新编写该文件。
即使对于较大的文件,也不会很难加载到内存中。在多演出内存的时代,我会考虑在内存中轻松完成数百兆字节。
你测试过这种天真的方法吗?你有没有看到它的真正问题?
如果这是一个非常大的文件(大小为千兆字节),我会考虑首先将所有数据写入临时文件,然后首先写入标题行的正确文件,然后附加其余数据。由于它只是文本,我可能只是向DOS发出声明:
TYPE temp.txt >> outfile.txt
答案 2 :(得分:2)
你确定吗? 如果你在文件的第一行写一个大数字(UInt32.MaxValue或UInt64.MaxValue),那么当你找到正确的实际数字时,你可以用正确的数字替换这个字节数,但是用零填充,所以它仍然是一个有效的整数。 e.g。我不需要更换“固定的 字节数“
Replace 999999 - your "large number placeholder"
With 000100 - the actual number of accounts
答案 3 :(得分:2)
如果我正确理解了这个问题,请告诉我?
C#/ .NET中打开文件的最佳方式是什么(在本例中是一个简单的文本文件),并替换文本第一行“数据”中的数据?
首次创建令牌{UserCount}时,如何在文件顶部放置。
然后使用TextReader逐行读取文件。如果它是{UserCount}的第一行,则替换为您的值。使用TextWriter
写出您读入的每一行示例:
int lineNumber = 1;
int userCount = 1234;
string line = null;
using(TextReader tr = File.OpenText("OriginalFile"))
using(TextWriter tw = File.CreateText("ResultFile"))
{
while((line = tr.ReadLine()) != null)
{
if(lineNumber == 1)
{
line = line.Replace("{UserCount}", userCount.ToString());
}
tw.WriteLine(line);
lineNumber++;
}
}
答案 4 :(得分:1)
如果提取的文件只有几百兆字节,那么您可以轻松地将所有文本保留在内存中,直到提取完成为止。然后,您可以将输出文件写为最后一个操作,从记录计数开始。
答案 5 :(得分:1)
好的,早些时候我提出了一种方法,如果处理现有文件会更好。
但是在您的情况下,您想要创建文件,并在创建过程中返回到顶部并写出用户计数。这样就可以了。
这是一种方法,可以防止你必须编写临时文件。
private void WriteUsers()
{
string userCountString = null;
ASCIIEncoding enc = new ASCIIEncoding();
byte[] userCountBytes = null;
int userCounter = 0;
using(StreamWriter sw = File.CreateText("myfile.txt"))
{
// Write a blank line and return
// Note this line will later contain our user count.
sw.WriteLine();
// Write out the records and keep track of the count
for(int i = 1; i < 100; i++)
{
sw.WriteLine("User" + i);
userCounter++;
}
// Get the base stream and set the position to 0
sw.BaseStream.Position = 0;
userCountString = "User Count: " + userCounter;
userCountBytes = enc.GetBytes(userCountString);
sw.BaseStream.Write(userCountBytes, 0, userCountBytes.Length);
}
}