繁体   English   中英

使用C#/ .NET替换文件中文本的最佳方法是什么?

[英]What is the BEST way to replace text in a File using C# / .NET?

我有一个文本文件,作为一个非常大的数据提取的一部分写入。 文本文件的第一行是提取的“帐户”数。

由于此提取的性质,该数字直到过程的最后才知道,但文件可能很大(几百兆)。

在C#/ .NET中打开文件(在本例中是一个简单的文本文件),并替换文本的第一个“行”中的数据的最佳方法是什么?

重要说明 : - 我不需要替换“固定数量的字节” - 这很容易。 这里的问题是需要插入文件顶部的数据是可变的。

重要说明2 : - 有些人询问/提到只是将数据保存在内存中然后更换它......但这完全是不可能的。 更新此过程的原因是因为有时它会在将几个演出加载到内存时崩溃。

如果可以的话,您应该插入一个占位符,并在末尾覆盖实际的数字和空格。

如果这不是一个选项,请先将数据写入缓存文件。 当您知道实际数字时,创建输出文件并附加缓存中的数据。

BEST非常主观。 对于任何小文件,您可以轻松地在内存中打开整个文件,并使用字符串替换替换您想要的内容,然后重新编写该文件。

即使对于较大的文件,也不会很难加载到内存中。 在多内存的时代,我会考虑在内存中轻松完成数百兆字节。

你测试过这种天真的方法吗? 你有没有看到它的真正问题?

如果这是一个非常大的文件(大小为千兆字节),我会考虑首先将所有数据写入临时文件,然后写入正确的文件,首先进入标题行,然后附加其余数据。 由于它只是文本,我可能只是向DOS发出声明:

 TYPE temp.txt >> outfile.txt

我不需要替换“固定数量的字节”

你确定吗? 如果你在文件的第一行写一个大数字(UInt32.MaxValue或UInt64.MaxValue),那么当你找到正确的实际数字时,你可以用正确的数字替换这个字节数,但是用零填充,所以它仍然是一个有效的整数。 例如

Replace  999999 - your "large number placeholder"
With     000100 - the actual number of accounts

如果我正确理解了这个问题,对我来说似乎?

在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++;
        }

    }

如果提取的文件只有几百兆字节,那么您可以轻松地将所有文本保留在内存中,直到提取完成。 然后,您可以将输出文件写为最后一个操作,从记录计数开始。

好的,早些时候我提出了一种方法,如果处理现有文件会更好。

但是在您的情况下,您希望创建该文件,并在创建过程中返回到顶部并写出用户计数。 这样就可以了。

这是一种方法,可以防止您必须编写临时文件。

    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);
        }

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM