在C#中创建一个空文件


186

在C#/。NET中创建空文件的最简单/规范的方法是什么?

到目前为止,我能找到的最简单的方法是:

System.IO.File.WriteAllLines(filename, new string[0]);

Answers:


384

使用just File.Create将使文件保持打开状态,这可能不是您想要的。

您可以使用:

using (File.Create(filename)) ;

请注意,这看起来有些奇怪。您可以改用大括号:

using (File.Create(filename)) {}

或直接致电Dispose

File.Create(filename).Dispose();

无论哪种方式,如果要在一个以上的地方使用它,都应该考虑将其包装在辅助方法中,例如

public static void CreateEmptyFile(string filename)
{
    File.Create(filename).Dispose();
}

请注意,据我所知,在这里Dispose直接调用而不使用using语句并没有多大区别-唯一可以改变的方法是,线程在调用File.Create和调用之间被中止Dispose。如果那场比赛条件存在,我怀疑这会存在于using版本,如果线程均在的最后中止File.Create方法,返回值之前...


8
滑稽。我大约在5分钟前编写了相同的代码。我做了File.Create(filename).Close(); 同样的差异...
Brian Genisio

2
我的代码正在使用using (File.Create(filename)) ;,但我喜欢它的简单性File.Create(filename).Dispose();
Vadim 2013年

@BrianGenisio:我也大约在5分钟前做了同样的代码!我只是在谷歌上看看其他程序员是如何做到的。现在,我使用File.Create(filename).Dispose();代替。
杰克

1
@ user3791372:Close()也会释放资源。Close()只是调用Dispose-看github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/...
乔恩斯基特

1
如果文件已经存在并且不是只读的,则文件内容将被覆盖,这可能并不明显。为避免这种情况,请使用using (new FileStream(filename, FileMode.CreateNew)) { }
Phil Haselden

34
File.WriteAllText("path", String.Empty);

要么

File.CreateText("path").Close();

2
使用第一个,文件的长度为3个字节:编码代码。使用第二个,文件为0字节(真的为空)。
费尔

1
@Fil:确定吗?文档说的是File.WriteAllText(string, string)使用“UTF-8编码没有字节顺序标记(BOM)”。如果仍然看到一个,那可能是WriteAllText或其报告中值得报告的错误。
Heinzi

我记得我曾经尝试过。也许是以前的.Net版本的旧错误?如果我明确指定使用UTF8编码(或unicode或其他方式),则文件不为空:<File.WriteAllText(“ c:\ del.txt”,String.Empty,System.Text.Encoding.UTF8);>
2016年

1
@Fil,Encoding.UTF8返回一个输出字节顺序标记(BOM)的编码器。您可以new UTF8Encoding(false)用来获取不输出BOM的UTF8编码器。
丹尼尔·克拉布特里

1
不知道WriteAllText在.NET的先前版本中是否确实表现出不同。但是,要特别确定的是,只需跳过编码部分并File.WriteAllBytes(path, new byte[] { });改为使用。
于尔根Steinblock

20
System.IO.File.Create(@"C:\Temp.txt");

正如其他人指出的那样,您应该处置此对象或将其包装在空的using语句中。

using (System.IO.File.Create(@"C:\Temp.txt"));

4
会更好地处置物体吗?例如:使用(System.IO.File.Create(filepath)){}
kentaromiura

@kentaromiura:我的想法完全正确,因此我的回答是:)
Jon Skeet

4

您可以将方法链接到返回的对象上,因此可以立即关闭在单个语句中刚刚打开的文件。

File.Open("filename", FileMode.Create).Close();

4

为避免意外覆盖现有文件,请使用:

using (new FileStream(filename, FileMode.CreateNew)) {}

...并处理如果文件已存在将发生的IOException。

File.Create在其他答案中建议的,将覆盖如果文件已存在的内容。在简单的情况下,您可以使用减轻这种情况File.Exists()。但是,在多个线程和/或进程试图同时在同一文件夹中创建文件的情况下,需要更强大的功能。


2

创建空文件的一种常见用法是在缺少更复杂的过程通信的情况下触发其他过程中发生的其他事情。在这种情况下,从外部世界的角度来看,使文件创建成为原子是有帮助的(特别是如果要触发的事物将要删除文件以“使用”触发器)。

因此,它可以帮助在要创建的文件所在的目录中创建垃圾名称(Guid.NewGuid.ToString()),然后执行File.Move从临时名称更改为所需的名称。否则,检查文件存在然后删除触发器的触发代码可能会陷入竞争状态,在这种情况下,文件被完全关闭之前已被删除。

将temp文件放在相同的目录(和文件系统)中可为您提供所需的原子性。这给像。

public void CreateEmptyFile(string path)
{
    string tempFilePath = Path.Combine(Path.GetDirectoryName(path),
        Guid.NewGuid.ToString());
    using (File.Create(tempFilePath)) {}
    File.Move(tempFilePath, path);
}

0

Path.GetTempFileName()将创建一个唯一命名的空文件,并返回其路径。

如果要控制路径但获得随机文件名,则可以使用GetRandomFileName来返回文件名字符串,并将其与Create一起使用

例如:

string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);

恕我直言GetTempFileName()完全被错误命名。
kay.herzam,2009年

为什么这个答案无济于事?
Crippledsmurf

5
它没有帮助,有两个原因:1.该问题对生成随机文件名没有任何要求,因此很分散注意力。2.文件不会关闭,这意味着如果您以后尝试打开另一个文件写入器或移动文件,它将失败。
萨蒂亚河

我的意思是:1.所有文件都需要一个名称。那很简单。获得一个不太可能与任何东西冲突的简便方法2.关于创建文件的问题,所讨论的代码确实可以做到这一点,至少,此后对文件的管理并不是严格意义上的创建,因此在此我省略了它。为了简单起见,并始终将答案集中在问题上
Crippledsmurf 2015年
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.