如果不存在,则创建一个 .txt 文件,如果它确实追加一个新行
Posted
技术标签:
【中文标题】如果不存在,则创建一个 .txt 文件,如果它确实追加一个新行【英文标题】:Create a .txt file if doesn't exist, and if it does append a new line 【发布时间】:2012-04-12 01:19:46 【问题描述】:我想创建一个 .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# 完全陌生。
【问题讨论】:
请注意,这里几乎所有的答案都是错误的,并且受制于竞争条件。请记住:模式if (file exists) open file
在所有编程语言中几乎总是错误的!对于 .NET,解决方案是使用带有适当标志的 File.Open(path, FileMode.Append, FileAccess.ReadWrite)
。
“一个 FileMode 值,它指定一个文件不存在时是否创建,并确定现有文件的内容是保留还是覆盖。”所以同样的事情是由 .net 完成的,而不是这里的手动方法。所以这里没有错,它是手动完成的相同过程。你可以说效率低下,但说错了不算数。
不同之处在于:File.Open
在内部委托给一个 WinAPI 函数(见下一条评论),希望能防止竞争条件。这里的大多数解决方案都不会这样做,并且很明显会受到竞争条件的影响。
存在性检查是由 FileMode.Append 确定的。它指向存在性检查,然后使用 CreateFileA 创建文件。仍然说错有点极端,但你可以说效率低下。我们也不应该忘记存在检查可能不仅仅用于写/读访问,也可能用于其他事务,所以对于新手来说,这个主题有助于理解它是如何工作的。但是,如果您可以添加一个答案,包括您在此处编写的所有定义以及为什么它更好的原因,这将作为一个答案有很大帮助,并且可能会被选为正确的。
@ComFreek 我强烈同意你应该写一个完整的答案来清楚地解释它。评论不是用来回答的,我对这些竞态条件以及您提出的解决方案非常好奇。
【参考方案1】:
使用correct constructor:
else if (File.Exists(path))
using(var tw = new StreamWriter(path, true))
tw.WriteLine("The next line!");
【讨论】:
第一个答案,最简单的答案,对我来说最有用的答案哈哈。当我看着它时,我就像:嗯?只需添加“,true”就足够了吗?我以前怎么看不到?该死的......我觉得完全是愚蠢的谢谢。我真的很欣赏这些不错的答案。 提示:如果文件不存在,这个构造函数会创建一个新文件。 将 i 包裹在 using 中(请参阅下面的答案)。 关闭是多余的,如果你有使用 -1 这受竞争条件的影响,可能会产生错误的行为!也许宁愿使用File.Open(path, FileMode.Append, FileAccess.ReadWrite)
并通过返回的流检查文件大小。【参考方案2】:
string path = @"E:\AppServ\Example.txt";
File.AppendAllLines(path, new [] "The very first line!" );
另见 File.AppendAllText()。 AppendAllLines 将为每一行添加一个换行符,而无需自己将其放在那里。
如果文件不存在,这两种方法都会创建文件,因此您不必这样做。
File.AppendAllText File.AppendAllLines【讨论】:
我认为这更适合用户的要求。好像有2个问题。 1 是文本被覆盖 - 这是因为 WriteLine 正在覆盖文件。在这种情况下,File.AppendAllText 更合适。和 2) - 我如何创建我的文件并知道我正在附加它的问题。很高兴知道 File.AppendAllText 创建文件,这是我的问题。 StreamWriter 并不总是合适的,它取决于该应用程序的用途。无论哪种情况,这都帮助了我。 +1 为什么这不是最佳答案? 3 行并使用 .net 库【参考方案3】: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()。我的目标不涉及复制粘贴。 我不建议这样做;我的意思是,如果不将其包含在您的答案中,原始发布者将不知道您为什么做出更改或他们应该完成的更改。发布时请务必包含所有相关信息,以便人们知道您在做什么。 :) 这是有效的,因为它不会给出一个错误,指出您无法写入新创建的文件,因为它正在被另一个进程使用。 .Dispose() 是关键。非常感谢! 这并不能解决问题,即保留现有内容。 从using
语句中调用Close()
是没有意义的,因为所有资源都会在自动释放之前关闭。【参考方案4】:
您实际上不必检查文件是否存在,因为 StreamWriter 会为您完成。如果您以追加模式打开它,如果文件不存在,则将创建该文件,然后您将始终追加并且永远不会覆盖。所以你的初始检查是多余的。
TextWriter tw = new StreamWriter(path, true);
tw.WriteLine("The next line!");
tw.Close();
【讨论】:
我试图找出接受答案的逻辑,我知道我之前已经在一行中完成了此操作,但不记得确切的语法。谢谢。【参考方案5】:File.AppendAllText 将字符串添加到文件中。如果文件不存在,它还会创建一个文本文件。如果您不需要阅读内容,它非常有效。用例是日志记录。
File.AppendAllText("C:\\log.txt", "hello world\n");
【讨论】:
这正是我所需要的,但我怎样才能让新内容从新行开始呢?我正在使用 CSV 文件。 我想没有一个简单的解决方案。我建议你看看这个帖子。 ***.com/questions/1343044/… 非常好的和简单的解决方案。非常感谢。【参考方案6】:您只想以“追加”模式打开文件。
http://msdn.microsoft.com/en-us/library/3zc0w663.aspx
【讨论】:
是的,这也很有用,但我一直在寻找一种快速简单的解决方案,感谢@Daniel Hilgarth,他提供了那种解决方案。所以+1。【参考方案7】:您可以只使用 File.AppendAllText() 方法这将解决您的问题。 如果不可用,此方法将负责创建文件,打开和关闭文件。
var outputPath = @"E:\Example.txt";
var data = "Example Data";
File.AppendAllText(outputPath, data);
【讨论】:
【参考方案8】:当您启动 StreamWriter 时,它会覆盖之前的文本。您可以像这样使用附加属性:
TextWriter t = new StreamWriter(path, true);
【讨论】:
【参考方案9】: else if (File.Exists(path))
using (StreamWriter w = File.AppendText(path))
w.WriteLine("The next line!");
w.Close();
【讨论】:
如果你有 `using' 块, w.Close 是多余的。使用块结束时的 Dispose 也是如此。 -1 这受竞争条件的影响,可能会产生错误的行为!也许宁愿使用File.Open(path, FileMode.Append, FileAccess.ReadWrite)
并通过返回的流检查文件大小。【参考方案10】:
试试这个。
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!");
【讨论】:
RedudantFile.AppendText(path)
,因此无需检查File.Exists(path)
。 If (not A) Else If (A)
是一个奇怪的 If/Else。基本上这个问题没有什么好的,没有解释代码是其他答案的冗余版本。
-1 这受竞争条件的影响,可能会产生错误的行为!也许宁愿使用File.Open(path, FileMode.Append, FileAccess.ReadWrite)
并通过返回的流检查文件大小。
关于 File.AppendText,根据其参考:“创建一个 StreamWriter,将 UTF-8 编码文本附加到现有文件,如果指定文件不存在,则附加到新文件。”跨度>
【参考方案11】:
您可以使用 FileStream。这将为您完成所有工作。
http://www.csharp-examples.net/filestream-open-file/
【讨论】:
【参考方案12】:从 microsoft 文档中,您可以创建文件(如果不存在)并在一次调用中附加到它 File.AppendAllText 方法(String, String)
.NET Framework(当前版本)其他版本
打开一个文件,将指定的字符串附加到文件中,然后关闭文件。如果文件不存在,此方法创建一个文件,将指定的字符串写入文件,然后关闭文件。 命名空间:System.IO 程序集:mscorlib(在 mscorlib.dll 中)
语法 C#C++F#VB 公共静态无效AppendAllText( 字符串路径, 字符串内容 ) 参数 小路 类型:System.String 要将指定字符串附加到的文件。 内容 类型:System.String 要附加到文件的字符串。
AppendAllText
【讨论】:
【参考方案13】:using(var tw = new StreamWriter(path, File.Exists(path)))
tw.WriteLine(message);
【讨论】:
一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。【参考方案14】:.NET Core 控制台应用程序:
public static string RootDir() => Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, @"..\..\..\"));
string _OutputPath = RootDir() + "\\Output\\" + "MyFile.txt";
if (!File.Exists(_OutputPath))
File.Create(_OutputPath).Dispose();
using (TextWriter _StreamWriter = new StreamWriter(_OutputPath))
_StreamWriter.WriteLine(strOriginalText);
【讨论】:
以上是关于如果不存在,则创建一个 .txt 文件,如果它确实追加一个新行的主要内容,如果未能解决你的问题,请参考以下文章
文件存在,如果语句检查,如果文件不存在,则不会返回正确的输出,C#