创建一个.txt文件(如果不存在),并添加新行


161

我想创建一个.txt文件并将其写入,如果该文件已经存在,我只想追加一些行:

string path = @"E:\AppServ\Example.txt";
if (!File.Exists(path))
{
    File.Create(path);
    TextWriter tw = new StreamWriter(path);
    tw.WriteLine("The very first line!");
    tw.Close();
}
else if (File.Exists(path))
{
    TextWriter tw = new StreamWriter(path);
    tw.WriteLine("The next line!");
    tw.Close(); 
}

但是第一行似乎总是被覆盖...如何避免在同一行上写(我在循环中使用它)?

我知道这是一件非常简单的事情,但是我以前从未使用过该WriteLine方法。我是C#的新手。


3
请注意,这里几乎所有答案都是错误的,并受比赛条件的影响。请记住:if (file exists) { open file }在所有编程语言中,模式几乎总是错误的!对于.NET,解决方案是使用File.Open(path, FileMode.Append, FileAccess.ReadWrite)适当的标志。
ComFreek

“一个FileMode值,它指定在不存在的情况下是否创建文件,并确定是保留还是覆盖现有文件的内容。” 因此,.net可以完成相同的工作,而不是此处的手动方法。因此,这里没有错,它是手动完成的相同过程。您可能会说效率低下,但说错并不重要。
BerkerYüceer19年

区别在于:File.Open内部委托WinAPI函数(请参阅下一条注释)有望防止出现竞争情况。这里的大多数解决方案都不会这样做,并且很明显要受比赛条件的影响。
ComFreek

1
但是,存在检查由FileMode.Append此处确定。它指向存在检查,然后使用CreateFileA创建文件。仍然说错了一些极端,但是您可以说效率低下。我们也不应忘记,存在性检查可能不仅仅用于写/读访问,也可能被其他事务使用,因此对于新手来说,本主题对于理解其工作原理很有用。但是,如果您可以添加包括您在此处编写的所有定义的答案,以及为什么更好的原因,这将对答案有很大帮助,并且可能会被选择为正确的答案。
BerkerYüceer,

1
@ComFreek我非常同意您应该写一个完整的答案以清楚地说明它。评论不代表回答,我对这些比赛条件以及您提出的解决方法表示衷心的好奇。
Matthieu Foltzer

Answers:


167

使用正确的构造函数

else if (File.Exists(path))
{
    using(var tw = new StreamWriter(path, true))
    {
        tw.WriteLine("The next line!");
    }
}

11
第一答案,最简单的答案,对我来说最有用的答案。当我看着它时,我就像:呵呵?仅添加“,true”就足够了吗?我怎么会以前看不到呢?该死的……我总觉得很傻。我真的很喜欢这些好答案。
BerkerYüceer2012年

7
提示:如果文件不存在,则此构造方法将创建一个新文件。
2016年

1
将我包装在使用中(请参见下面的答案)。
David Thielen

1
如果您使用的话,关闭是多余的
Michael Freidgeim

2
-1这取决于比赛条件,并且可能产生错误的行为!也许可以File.Open(path, FileMode.Append, FileAccess.ReadWrite)通过返回的流使用并检查文件大小。
ComFreek

57
string path = @"E:\AppServ\Example.txt";
File.AppendAllLines(path, new [] { "The very first line!" });

另请参见File.AppendAllText()。AppendAllLines会在每行中添加一个换行符,而不必自己放置。

如果文件不存在,则这两种方法都会创建该文件,因此您不必这样做。


3
我认为这更适合用户的要求。听起来好像有2个问题。1是文本被覆盖-这是因为WriteLine正在覆盖文件。在这种情况下,File.AppendAllText更合适。和2)-如何创建文件并知道要附加到文件的问题。很高兴File.AppendAllText创建文件,这是我的问题。StreamWriter并不总是合适的,它取决于该应用程序的用途。无论哪种情况,这都帮助了我。+1
Devin C

42
string path=@"E:\AppServ\Example.txt";

if(!File.Exists(path))
{
   File.Create(path).Dispose();

   using( TextWriter tw = new StreamWriter(path))
   {
      tw.WriteLine("The very first line!");
   }

}    
else if (File.Exists(path))
{
   using(TextWriter tw = new StreamWriter(path))
   {
      tw.WriteLine("The next line!");
   }
}

我也遇到了同样的问题,找到了这张海报,但是这里的解决方案无法解决我的问题。所以我使用一些解决方案,只添加Dispose()。我的目标不涉及复制粘贴。
2013年

1
我不建议这样做。我是说,如果您的答案没有包括在内,原始的发帖人将不知道您为什么进行了更改或应该完成哪些更改。发布时始终包括所有相关信息,以便人们知道您正在做的所有事情。:)
DiMono

1
之所以有效,是因为它不会给出错误消息,表明您无法写入新创建的文件,因为该文件正在被另一个进程使用。.Dispose()是关键。非常感谢!
GenXisT 2014年

这绝不能解决有关保留现有内容的问题。
Ben Voigt 2014年

Close()using语句中调用是没有意义的,因为所有资源将在自动处置之前被关闭。
谢里登

21

实际上,您不必检查文件是否存在,因为StreamWriter会为您完成此操作。如果以追加模式打开文件,则该文件将在不存在的情况下被创建,那么您将始终追加文件,并且永远不会被覆盖。因此,您的初始检查是多余的。

TextWriter tw = new StreamWriter(path, true);
tw.WriteLine("The next line!");
tw.Close(); 

1
我试图弄清楚接受答案的逻辑,我知道我之前已经完成了这一行,但是记不清确切的语法。谢谢。
Morvael

14

File.AppendAllText将字符串添加到文件。如果该文件不存在,还将创建一个文本文件。如果您不需要阅读内容,这将非常有效。用例是日志记录。

File.AppendAllText("C:\\log.txt", "hello world\n");

这正是我所需要的,但是我怎样才能使新内容从新的一行开始?我正在使用CSV文件。
NiallUK

我猜没有一个简单的解决方案。我建议您查看此帖子。stackoverflow.com/questions/1343044/...
R.Cha





2

试试这个。

string path = @"E:\AppServ\Example.txt";
if (!File.Exists(path))
{
    using (var txtFile = File.AppendText(path))
    {
        txtFile.WriteLine("The very first line!");
    }
}
else if (File.Exists(path))
{     
    using (var txtFile = File.AppendText(path))
    {
        txtFile.WriteLine("The next line!");
    }
}

冗余 File.AppendText(path),并且无需检查File.Exists(path)。并且If (not A) Else If (A)是一个奇怪的If / Else。基本上,这个问题没有什么好处,没有解释代码可以作为其他答案的冗余版本。
xdtTransform

-1这取决于比赛条件,并且可能产生错误的行为!也许可以File.Open(path, FileMode.Append, FileAccess.ReadWrite)通过返回的流使用并检查文件大小。
ComFreek

2

您可以只使用File.AppendAllText()方法来解决您的问题。如果不可用,此方法将负责文件创建,打开和关闭文件。

var outputPath = @"E:\Example.txt";
var data = "Example Data";
File.AppendAllText(outputPath, data);

1

从Microsoft文档中,您可以创建文件(如果不存在)并将其追加到单个调用File.AppendAllText方法(字符串,字符串)中

.NET Framework(当前版本)其他版本

打开一个文件,将指定的字符串附加到该文件,然后关闭该文件。如果该文件不存在,则此方法将创建一个文件,将指定的字符串写入该文件,然后关闭该文件。命名空间:System.IO程序集:mscorlib(在mscorlib.dll中)

语法C#C ++ F#VB public static void AppendAllText(字符串路径,字符串内容)参数path类型:System.String将指定字符串附加到的文件。contents类型:System.String要追加到文件的字符串。

AppendAllText


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.