tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

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()を使ってはいけない」は削除しました。

簡単ながら、訂正記事も書いたので、あわせてどうぞ。