我有一个包含以下内容的测试文件:
1,2,3
2,3,4
5,6,7
我想把A,B,C
插入到第一行:
这样我就得到了:
A,B,C
1,2,3
2,3,4
5,6,7
我该如何做到这一点?
我有一个包含以下内容的测试文件:
1,2,3
2,3,4
5,6,7
我想把A,B,C
插入到第一行:
这样我就得到了:
A,B,C
1,2,3
2,3,4
5,6,7
我该如何做到这一点?
与之前的答案类似,但这里展示了如何在最小化内存消耗的情况下完成你想要做的事情。即使你将其打开为读/写流,你也无法“插入”数据,因此你需要阅读整个要修改的文件。
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);
}
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");
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<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(换行符)
组成。结果保存在单独的文件中(仅供测试使用)。fileInput
变量中指定)启动了 5 次代码。每次启动时,执行 WriteABC
和 WriteABC2
函数各 100 次。 | 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 |
|-----|-------|--------|
file10000.txt
开始变得明显。http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=132
尽管这是特定于C#的,但在许多语言中,方法可能相对相同。在文本文件中无法“插入”任何内容。
您将需要:
@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