C# 如何在文本文件的第一行插入行?

C# 如何在文本文件的第一行插入行?,c#,C#,我有一个测试文件,其中包含 1,2,3 2,3,4 5,6,7 我想把它插入第一行:A,B,C 因此,我得到: A,B,C 1,2,3 2,3,4 5,6,7 我如何才能做到这一点?这里有一个链接,解释了如何在C#中使用TextReader(StreamReader)和TextWriter(StreamWriter)类 尽管这是C#特有的,但在许多语言中,这种方法可能是相对相同的 (注意:有几种方法可以做到这一点,这只是一个很快浮现在脑海中的想法。) 基本上,您可以将文本文件的内容读入一个

我有一个测试文件,其中包含

1,2,3
2,3,4
5,6,7
我想把它插入第一行:
A,B,C

因此,我得到:

A,B,C
1,2,3
2,3,4
5,6,7

我如何才能做到这一点?

这里有一个链接,解释了如何在C#中使用TextReader(StreamReader)和TextWriter(StreamWriter)类

尽管这是C#特有的,但在许多语言中,这种方法可能是相对相同的

(注意:有几种方法可以做到这一点,这只是一个很快浮现在脑海中的想法。)


基本上,您可以将文本文件的内容读入一个字符串,找到该字符串的开头,写入信息(使用回车符或换行符a、B、C),然后将该信息写回文本文件,覆盖原始内容并保存。

您不能在文本文件中“插入”任何内容

你必须

  • 复制内容
  • 在适当的时间提供额外的数据
  • 关闭文件
  • 删除原始名称并将新名称重命名为旧名称

与前面的答案类似,但这说明了如何在最小化内存消耗的同时做您想做的事情。即使在读/写流中打开文件,也无法读取要修改的整个文件,因为无法“插入”数据


我认为这个答案更简单、更快:

public static void WriteToFile(string Path, string Text)
{
    string content = File.ReadAllText(Path);
    content = Text + "\n" + content;      
    File.WriteAllText(Path, content);
}
那么你可以称之为:

WriteToFile("yourfilepath", "A,B,C");

@杰克:StringBuilder更好更简单

public static void WriteToFile(string path, string text)
{
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.AppendLine("a,b,c");
        stringBuilder.Append(File.ReadAllText(path)).AppendLine();
        File.WriteAllText(path, stringBuilder.ToString()); 
}
编辑: 但是StringBuilder有一个缓冲区限制:最大容量2147483647晚到派对

好问题。您可以使用以下代码:

static void WriteABC2(string filename)
{
    string tempfile = Path.GetTempFileName();
    using (var writer = new FileStream(tempfile, FileMode.Create))
    using (var reader = new FileStream(filename, FileMode.Open))
    {
        var stringBytes = Encoding.UTF8.GetBytes("A,B,C" + Environment.NewLine);
        writer.Write(stringBytes, 0, stringBytes.Length);

        reader.CopyTo(writer);
    }
    File.Copy(tempfile, filename, true);
    File.Delete(tempfile);
}
此代码基于出色的答案,但我使用
FileStream
而不是
StreamWriter
StreamReader
。在处理大文件时,使用
FileStream
可以大大提高性能(比我的测试快4倍)。只是想说清楚一点,我做了一些测试,并在下面报告了结果

我是如何做测试的 我创建了7个文件。每个文件包含10^X行,其名称为
file.txt
。因此,文件列表如下所示:

| File name       | Line count | File size |
|-----------------|------------|-----------|
| file1.txt       |          1 | 66 byte   |
| file10.txt      |         10 | 678 byte  |
| file100.txt     |        100 | 6,72 KB   |
| file1000.txt    |       1000 | 68,2 KB   |
| file10000.txt   |      10000 | 692 KB    |
| file100000.txt  |     100000 | 6,85 MB   |
| file1000000.txt |    1000000 | 69,5 MB   |
每个文件的每一行由以下内容组成:

<line index starting from 0> - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
我使用以下代码进行测试并获得函数执行持续时间:

var stopwatch = new Stopwatch();

long abcTotalDuration = 0;
long abc2TotalDuration = 0;

string fileInput = "file1.txt";
string outputFolder = "output";

for (int i = 0; i < 100; i++)
{
    string filename1 = Path.Combine(outputFolder, Guid.NewGuid().ToString());
    string filename2 = Path.Combine(outputFolder, Guid.NewGuid().ToString());

    stopwatch.Restart();
    WriteABC(fileInput, filename1);
    stopwatch.Stop();
    abcTotalDuration += stopwatch.ElapsedMilliseconds;

    stopwatch.Restart();
    WriteABC2(fileInput, filename2);
    stopwatch.Stop();
    abc2TotalDuration += stopwatch.ElapsedMilliseconds;

    File.Delete(filename1);
    File.Delete(filename2);
}

Console.WriteLine("ABC : " + abcTotalDuration.ToString());
Console.WriteLine("ABC2: " + abc2TotalDuration.ToString());

// Just to wake me up :-)
Console.Beep(800, 1000);

Console.ReadKey();

处理文件10.txt


处理文件100.txt


处理文件1000.txt


处理文件10000.txt


处理文件100000.txt


处理文件1000000.txt


file10000.txt

中,差异变得非常显著。如果您的文件是10MB或100MB,该怎么办?你能把这些都读入一个字符串(在内存中)吗?这不是很有效。+1-诱惑是相信你可以在文件的开头“插入”一行,而剩下的就完好无损了。它不是那样工作的,所以你指出它是对的。约书亚确实提到了StreamReader和StreamWriter。如果Gold同时使用这两种方法,那么它可以一行一行地完成,这同样不是很有效,但它可以工作而不必担心OutOfMemoryException。答案是:“您可以将文本文件的内容读入字符串”。这只是一个坏主意,除非你确信文件永远不会超过某个大小(取决于你的环境)。@rwwilden:你似乎在鼓吹不可能的事情。你检验过这个理论吗?请参阅对您答案的评论。@rwwilden:事实上,您只能“在末尾插入”,即追加,其他任何内容都会覆盖现有文件的一部分。很抱歉造成混淆,我的答案只覆盖部分文件,根本不插入。太棒了,但我想知道,我们应该是“file.Delete(tempfile)”吗是的,最好是删除文件,为什么还要留下我们不再需要的东西呢?这对较小的文件很好,但对于较大的文件,您可能会遇到内存问题。我们需要指定编码,否则,它会很好地读取文件,但会使用不同的编码写入文件。
0 - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
1 - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
var stopwatch = new Stopwatch();

long abcTotalDuration = 0;
long abc2TotalDuration = 0;

string fileInput = "file1.txt";
string outputFolder = "output";

for (int i = 0; i < 100; i++)
{
    string filename1 = Path.Combine(outputFolder, Guid.NewGuid().ToString());
    string filename2 = Path.Combine(outputFolder, Guid.NewGuid().ToString());

    stopwatch.Restart();
    WriteABC(fileInput, filename1);
    stopwatch.Stop();
    abcTotalDuration += stopwatch.ElapsedMilliseconds;

    stopwatch.Restart();
    WriteABC2(fileInput, filename2);
    stopwatch.Stop();
    abc2TotalDuration += stopwatch.ElapsedMilliseconds;

    File.Delete(filename1);
    File.Delete(filename2);
}

Console.WriteLine("ABC : " + abcTotalDuration.ToString());
Console.WriteLine("ABC2: " + abc2TotalDuration.ToString());

// Just to wake me up :-)
Console.Beep(800, 1000);

Console.ReadKey();
      | ABC | ABC2 |
      |-----|------|
      | 285 |  305 |
      | 356 |  352 |
      | 435 |  371 |
      | 355 |  313 |
      | 362 |  372 |
|-----|-----|------|
  AVG | 359 |  343 |
|-----|-----|------|
      | ABC | ABC2 |
      |-----|------|
      | 256 |  251 |
      | 273 |  323 |
      | 355 |  347 |
      | 350 |  314 |
      | 315 |  286 |
|-----|-----|------|
  AVG | 310 |  304 |
|-----|-----|------|
      | ABC | ABC2 |
      |-----|------|
      | 247 |  253 |
      | 239 |  246 |
      | 357 |  353 |
      | 387 |  334 |
      | 333 |  329 |
|-----|-----|------|
  AVG | 313 |  303 |
|-----|-----|------|
      | ABC  | ABC2  |
      |------|-------|
      |  977 |   924 |
      |  784 |   738 |
      |  818 |   764 |
      | 1142 |  1101 |
      |  975 |   903 |
|-----|------|-------|
  AVG |  939 |   886 |
|-----|------|-------|
      | ABC  | ABC2  |
      |------|-------|
      | 1150 |   748 |
      | 1147 |   811 |
      | 1069 |   654 |
      | 1181 |   799 |
      | 1234 |   805 |
|-----|------|-------|
  AVG | 1156 |   763 |
|-----|------|-------|
      | ABC  | ABC2  |
      |------|-------|
      | 5485 |  1769 |
      | 5268 |  1528 |
      | 5296 |  1555 |
      | 5308 |  1529 |
      | 5289 |  1553 |
|-----|------|-------|
  AVG | 5329 |  1587 |
|-----|------|-------|
      | ABC   | ABC2   |
      |-------|--------|
      | 49034 |  12633 |
      | 52116 |  12484 |
      | 51643 |  12109 |
      | 52022 |  12359 |
      | 53145 |  12716 |
|-----|-------|--------|
  AVG | 51592 |  12460 |
|-----|-------|--------|