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

时间:2010-03-08 13:22:02

标签: 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

我该怎么做?

6 个答案:

答案 0 :(得分:25)

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

static void WriteABC(string filename)
{
    string tempfile = Path.GetTempFileName();
    using (var writer = new StreamWriter(tempfile))
    using (var reader = new StreamReader(filename))
    {
        writer.WriteLine("A,B,C");
        while (!reader.EndOfStream)
            writer.WriteLine(reader.ReadLine());
    }
    File.Copy(tempfile, filename, true);
}

答案 1 :(得分:3)

我认为这个答案更容易,更快:

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

答案 2 :(得分:2)

这是一个解释如何在C#中使用TextReader(StreamReader)和TextWriter(StreamWriter)类的链接。

http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=132

虽然这是针对C#的,但在许多语言中,这种方法可能相对相同。

(注意:有几种方法可以做到这一点,这只是想到的一个想法。)

基本上,你可以将文本文件的内容读入一个字符串,找到该字符串的开头,写下你的信息(A,B,C和你的回车或换行符),然后把这些信息写回来进入文本文件覆盖原始内容并保存。

答案 3 :(得分:1)

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

你必须

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

答案 4 :(得分:1)

晚会......

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

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

此代码基于优秀的Jake答案,但我使用FileStream代替StreamWriterStreamReader。在处理大文件时,使用FileStream会有很大的性能提升(甚至比我的测试快4倍)。为了清楚一点,我做了一些测试,并在下面报告了结果。

我如何进行测试

我创建了7个文件。每个文件包含10 ^ X行,其名称为file<line count>.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

例如,file10.txt的前两行是:

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

测试包括为每个指定文件预先加A,B,C(new line)。结果保存在单独的文件中(仅用于测试)。

我为每个输入文件(在fileInput变量中指定)启动了5次代码。每次启动代码时,WriteABCWriteABC2函数都会执行100次。

以下是结果(全部以毫秒为单位):

处理 file1.txt

      | ABC | ABC2 |
      |-----|------|
      | 285 |  305 |
      | 356 |  352 |
      | 435 |  371 |
      | 355 |  313 |
      | 362 |  372 |
|-----|-----|------|
  AVG | 359 |  343 |
|-----|-----|------|

处理 file10.txt

      | ABC | ABC2 |
      |-----|------|
      | 256 |  251 |
      | 273 |  323 |
      | 355 |  347 |
      | 350 |  314 |
      | 315 |  286 |
|-----|-----|------|
  AVG | 310 |  304 |
|-----|-----|------|

处理 file100.txt

      | ABC | ABC2 |
      |-----|------|
      | 247 |  253 |
      | 239 |  246 |
      | 357 |  353 |
      | 387 |  334 |
      | 333 |  329 |
|-----|-----|------|
  AVG | 313 |  303 |
|-----|-----|------|

处理 file1000.txt

      | ABC  | ABC2  |
      |------|-------|
      |  977 |   924 |
      |  784 |   738 |
      |  818 |   764 |
      | 1142 |  1101 |
      |  975 |   903 |
|-----|------|-------|
  AVG |  939 |   886 |
|-----|------|-------|

处理 file10000.txt

      | ABC  | ABC2  |
      |------|-------|
      | 1150 |   748 |
      | 1147 |   811 |
      | 1069 |   654 |
      | 1181 |   799 |
      | 1234 |   805 |
|-----|------|-------|
  AVG | 1156 |   763 |
|-----|------|-------|

处理 file100000.txt

      | ABC  | ABC2  |
      |------|-------|
      | 5485 |  1769 |
      | 5268 |  1528 |
      | 5296 |  1555 |
      | 5308 |  1529 |
      | 5289 |  1553 |
|-----|------|-------|
  AVG | 5329 |  1587 |
|-----|------|-------|

处理 file1000000.txt

      | ABC   | ABC2   |
      |-------|--------|
      | 49034 |  12633 |
      | 52116 |  12484 |
      | 51643 |  12109 |
      | 52022 |  12359 |
      | 53145 |  12716 |
|-----|-------|--------|
  AVG | 51592 |  12460 |
|-----|-------|--------|

file10000.txt的差异变得非常显着。

答案 5 :(得分:0)

@Jake: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