存在しない場合、および新しい行を追加する場合は、.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 here ..によって決定され、存在チェックを指示して、CreateFileAでファイルを作成します。まだ少し極端に間違っていますが、効率が悪いと言えます。また、存在チェックが書き込み/読み取りアクセスにのみ使用されない可能性があるため、他の事柄でも使用される可能性があるため、新しいトピックの場合、このトピックはその動作を理解するのに役立ちます。ただし、ここで記述したすべての定義を含めて回答を追加できる場合、それがより良い理由は、回答として非常に役立ち、おそらく正しいものとして選択されます。
BerkerYüceer19年

1
@ComFreek私はあなたがそれを明確に説明するためにそれについて完全な答えを書くべきであることを強く同意します。コメントは答えるのではなく、私はこれらの競合状態とそれを解決するためにどのように提案するかについて心から興味があります。
Matthieu Foltzer

回答:


167

正しいコンストラクタを使用します

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

11
最初の答え、最も簡単な答え、私にとっては最も有用な答え笑。私がそれを見たとき、私は次のようでした。"、true"を追加するだけで十分ですか?どうして前にそれを見られないのですか?くそー...私は全くばかげた感謝のように感じました。私はこれらのちょっと良い答えを本当に高く評価しています。
BerkerYüceer2012年

7
ヒント:ファイルが存在しない場合、このコンストラクターは新しいファイルを作成します。
Abou-Emish 2016年

1
usingでiをラップします(以下の回答を参照)。
David Thielen 2017

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
デビン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()を追加するだけです。私の目的はコピーアンドペーストを含まないことです。
Aek

1
私はそれを提案していません。それを回答に含めないと、元の投稿者は、なぜあなたが変更を加えたのか、または彼らが何を達成することになっているのかを理解できないと言っています。投稿するときは常にすべての関連情報を含めてください。そうすることで、あなたがしていることのすべてを人々が知ることができます。:)
DiMono 2013

1
これが機能するのは、新しく作成されたファイルが別のプロセスで使用されているために書き込めないというエラーが発生しないためです。.Dispose()が重要です。どうもありがとうございます!
GenXisT 2014年

これは、既存のコンテンツを保持することに関する質問にはまったく対応していません。
Ben Voigt

すべてのリソースは自動的に破棄される前に閉じられるClose()ため、usingステートメントから呼び出しても意味がありません。
シェリダン

21

StreamWriterが代わりに行うので、ファイルが存在するかどうかを実際に確認する必要はありません。追加モードで開くと、ファイルが存在しない場合はファイルが作成され、常に追加されて上書きされることはありません。したがって、最初のチェックは冗長です。

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

1
受け入れられた回答のロジックを理解しようとしていましたが、これを1行で行ったことがあることは知っていましたが、正確な構文を思い出せませんでした。ありがとうございました。
Morvael、

14

File.AppendAllTextは、文字列をファイルに追加します。ファイルが存在しない場合は、テキストファイルも作成します。コンテンツを読む必要がない場合は、非常に効率的です。ユースケースはロギングです。

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

これは私が必要としていたことですが、新しいコンテンツを新しい行から始めるにはどうすればよいですか?CSVファイルを使用しています。
NiallUK

簡単な解決策はないと思います。この投稿をチェックすることをお勧めします。stackoverflow.com/questions/1343044/...
R.Cha


3

StreamWriterを起動すると、以前にあったテキストが上書きされます。次のように、appendプロパティを使用できます。

TextWriter t = new StreamWriter(path, true);

3
 else if (File.Exists(path)) 
{ 
  using (StreamWriter w = File.AppendText(path))
        {
            w.WriteLine("The next line!"); 
            w.Close();
        }
 } 

1
「using」ブロックがある場合、w.Closeは冗長です。使用ブロックの最後に破棄することも同じです。
Michael Freidgeim、2018

-1これは競合状態の影響を受け、間違った動作をする可能性があります!おそらくFile.Open(path, FileMode.Append, FileAccess.ReadWrite)、返されたストリームを介してファイルサイズを使用して確認することをお勧めします。
ComFreek


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

マイクロソフトのドキュメントから、存在しない場合はファイルを作成し、1回の呼び出しでファイルに追加できます。File.AppendAllTextメソッド(文字列、文字列)

.NET Framework(現在のバージョン)その他のバージョン

ファイルを開き、指定した文字列をファイルに追加して、ファイルを閉じます。ファイルが存在しない場合、このメソッドはファイルを作成し、指定された文字列をファイルに書き込んでから、ファイルを閉じます。名前空間:System.IOアセンブリ:mscorlib(mscorlib.dll内)

構文C#C ++ F#VB public static void AppendAllText(string path、string contents)パラメーターpath型:System.String指定された文字列を追加するファイル。contents型:System.Stringファイルに追加する文字列。

AppendAllText


1
using(var tw = new StreamWriter(path, File.Exists(path)))
{
    tw.WriteLine(message);
}

一般的に、回答にコードの目的、および他の人を紹介することなく問題を解決する理由の説明が含まれている場合、回答ははるかに役立ちます。
Tim Diekmann、2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.