C# で touch(空ファイルの作成)
空ファイルを作るとき、File/FileInfo の Create() は使ってはいけない。StreamWriter を使って、空ファイルを作るのが良さそう。
こんな感じ。
private void Touch(string path) { if ( !File.Exists(path) ) { StreamWriter toucher = new StreamWriter(path); toucher.Close(); } }
ダメな場合の、ちょっとした再現コード。(要 NUnit)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using NUnit.Framework; namespace TouchTest { [TestFixture] public class TouchTests { private string testFilePath = "test.txt"; [SetUp] public void SetUp() { if (File.Exists(testFilePath)) File.Delete(testFilePath); } [Test] public void TouchAndDeleteByStreamWriterTest() { Touch(testFilePath); Assert.IsTrue(File.Exists(testFilePath)); File.Delete(testFilePath); Assert.IsTrue(!File.Exists(testFilePath)); } //[Test] public void TouchAndDeleteByCreateTest() { File.Create(testFilePath);//Create で touch。これじゃダメ! Assert.IsTrue(File.Exists(testFilePath)); File.Delete(testFilePath); Assert.IsTrue(!File.Exists(testFilePath)); } private void Touch(string path) { if (!File.Exists(path)) { StreamWriter toucher = new StreamWriter(path); toucher.Close(); } } } }
TouchAndDeleteByCreateTest の[Test]のコメントをはずすと、NUnit のテストがこけます。
TouchTest.TouchTests.TouchAndDeleteByCreateTest: System.IO.IOException : 別のプロセスで使用されているため、プロセスはファイル 'C:\Documents and Settings\tsucchi\My Documents\Visual Studio 2008\Projects\TouchTest\TouchTest\bin\Release\test.txt' にアクセスできません。 TouchTest.TouchTests.TouchAndDeleteByStreamWriterTest: System.IO.IOException : 別のプロセスで使用されているため、プロセスはファイル 'C:\Documents and Settings\tsucchi\My Documents\Visual Studio 2008\Projects\TouchTest\TouchTest\bin\Release\test.txt' にアクセスできません。
逆に、コメントアウトしたままなら、テストは必ず成功します。
つまり冒頭のように、StreamWriter 使って touch しろってこと
まあそもそも、File/FileInfo Create に対する僕の誤解なんですけどね。
このメソッドはファイルを作るんじゃなくて、戻り値の Stream を使ってあれこれするのが正しい使い方みたい。
訂正
File.Create(testFilePath).Close() のようにして、Close() をすれば良いとのご指摘をいただきました。確認したところ、確かにその通りでした。ので、1行目「Create()を使ってはいけない」は削除しました。
簡単ながら、訂正記事も書いたので、あわせてどうぞ。