CodeGym /课程 /C# SELF /创建与删除文件

创建与删除文件

C# SELF
第 40 级 , 课程 0
可用

1. Introduction

看起来文件这东西很简单,创建它似乎比登天还容易:Windows 下右键点两下就完了。但在真实项目里,程序化地创建和删除文件是自动化和灵活性的关键。比如:

  • 在文本编辑器里用户按「保存」— 你的代码会创建一个新文件,把用户的作品写进去。
  • 事件日志服务在应用启动时自动创建日志文件。
  • 压缩程序或备份工具定期创建临时文件然后再删掉它们。
  • C# 的游戏做自动存档 — 创建或覆盖 save 文件。
  • 还有你(或你的脚本)会自动清理旧的临时文件夹,避免把磁盘堆满。

会自动创建和删除文件,是现代 .NET 开发者的基本功之一。

2. Quick operations via File

File creation

在 C# 里可以用好几种方法创建文件。最快最直接的就是用静态类 File。来试试:


// 在当前目录创建空文件 "myfile.txt"
File.Create("myfile.txt").Close(); // FileStream 需要关闭!
Console.WriteLine("文件 'myfile.txt' 已创建.");

重要提示:
方法 File.Create 返回一个 FileStream 对象,需要关闭(Close()),否则操作系统会抱怨文件“被占用”。如果不关闭,后续对同一文件的某些操作可能会意外失败。这是经典情况: "文件被另一个进程占用",但“另一个进程”往往就是你自己没关的流。

如果文件已存在,File.Create 会覆盖它(旧的被删掉,新建一个空的)。如果文件不存在 — 就创建它。

Ну и что толку от пустого файла?

通常新文件不是用来空着的,而是要写点东西进去。为此有方便的方法:

File.WriteAllText("welcome.txt", "你好,文件世界!");

这条命令会创建文件、写入字符串,并负责优雅地把门(文件)关好,避免出事。

Проверка существования файла

在创建新文件前,检查一下它是不是已经存在是有用的。否则可能不小心把重要东西覆盖了。


if (!File.Exists("important.txt"))
{
    File.WriteAllText("important.txt", "保存重要信息。");
    Console.WriteLine("File created.");
}
else
{
    Console.WriteLine("Such file already exists, you can come up with something else!");
}

3. Real-life example: "Saving user greeting"


Console.Write("请输入你的名字: ");
string name = Console.ReadLine();

string filename = $"{name}_greeting.txt";
string message = $"欢迎, {name}!";

// 检查这个文件是否存在
if (!File.Exists(filename))
{
    File.WriteAllText(filename, message);
    Console.WriteLine($"个人问候文件 {filename} 已创建.");
}
else
{
    Console.WriteLine($"文件 {filename} 已存在!是否覆盖? (y/n)");
    string answer = Console.ReadLine();
    if (answer?.ToLower() == "y")
    {
        File.WriteAllText(filename, message);
        Console.WriteLine($"文件 {filename} 已被覆盖.");
    }
    else
    {
        Console.WriteLine("保持原样,不做改动.");
    }
}

我们在做什么:

  • 检查文件是否存在(File.Exists)。
  • 如果没有 — 创建并写入文本(File.WriteAllText)。
  • 如果存在 — 问用户是否要覆盖。

4. File deletion

在 C# 中删除文件看起来有点黑客 feel……但其实很安全!也很简单:

Using File.Delete

File.Delete("myfile.txt");

如果文件不存在 — 没戏剧性发生!只要路径正确,什么也不会发生(不会抛错)。

Beginner traps

  • 如果文件被你自己的程序(或别的程序)打开,会抛出异常。
  • 如果路径写错了 — 会出现 ArgumentException

Recommendation: always check for existence


if (File.Exists("victim.txt"))
{
    File.Delete("victim.txt");
    Console.WriteLine("File deleted.");
}
else
{
    Console.WriteLine("Nothing to delete — such file was not found.");
}

5. Folders and files: creating a file structure

File creation в папке


string folder = "Data";
Directory.CreateDirectory(folder); // 如果没有文件夹就创建

string filename = Path.Combine(folder, "info.txt");
File.WriteAllText(filename, "这里存放秘密留言!");

重要: 如果你尝试在不存在的文件夹里创建文件,会抛异常。所以先调用 Directory.CreateDirectory(folder) 是正确的。这个方法如果文件夹已经存在也不会重复创建,所以调用是安全的。

6. Working with instances: FileInfo

对于“老派”或更进阶的场景,类 FileInfo 很实用:


FileInfo fi = new FileInfo("example.txt");

// 创建新文件(和 File.Create 一样,会创建空文件)
using (var fs = fi.Create())
{
    // 如果想可以写点东西
}

Console.WriteLine($"File 'example.txt' created using FileInfo.");

通过 FileInfo 删除:


FileInfo fi = new FileInfo("oldfile.txt");
if (fi.Exists)
{
    fi.Delete();
    Console.WriteLine("File deleted via FileInfo.");
}

Advantages FileInfo

如果你不仅仅做创建/删除,还会频繁读取文件属性或对同一文件做多种操作,用实例方式更方便(有时候在性能上也更好)。

7. Creating and cleaning "technical files"

假设应用在文件夹 "temp_data" 中积累临时文件,我们想删除所有以 "temp_" 开头的文件。


string tempFolder = "temp_data";
Directory.CreateDirectory(tempFolder);

for (int i = 1; i <= 5; i++)
{
    string tempFile = Path.Combine(tempFolder, $"temp_{i}.txt");
    File.WriteAllText(tempFile, $"测试数据 {i}");
}
Console.WriteLine("已创建 5 个临时文件。");

// 现在删除所有 temp_*.txt
foreach (string file in Directory.GetFiles(tempFolder, "temp_*.txt"))
{
    File.Delete(file);
    Console.WriteLine($"已删除文件: {file}");
}

对自动清理旧临时文件很管用。

8. Important details: exceptions and security

可能出的问题:

  • 没有写入/删除权限(例如在 C:\Windows
  • 文件被其他程序(或你自己)占用
  • 路径含有不允许的字符(例如 *?<>
  • 在你检查和删除之间文件被别的进程删掉了(是会有这种事的)

如何防护

在生产代码里,这类操作一般都用 try-catch 包起来:


try
{
    File.Delete("trickyfile.txt");
    Console.WriteLine("File deleted.");
}
catch (UnauthorizedAccessException ex)
{
    Console.WriteLine("No permission to delete the file.");
}
catch (IOException ex)
{
    Console.WriteLine("The file might be occupied by another process.");
}
catch (Exception ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}

9. Useful nuances

Files that are always under control

  • 使用 Path.Combine 来拼接路径。这样不会出现多余或缺失的斜杠,代码更跨平台。
  • 在创建/删除前检查文件是否存在,避免惊喜。
  • 在生产或特别是“多人使用”的应用里用 try-catch 包裹你的代码
  • 对同一个文件频繁操作用 FileInfo,一次性操作用 File
  • 不要把文件打开着比必要时间长。文件还开着?问问自己:"为什么还开着?" 然后关掉它!能用 using 的地方就用它。

Technical cheat sheet

操作 方法 备注
创建空文件
File.Create
返回 FileStream,需要关闭
写文本到文件
File.WriteAllText
创建文件或覆盖
检查是否存在
File.Exists
返回 bool
删除文件
File.Delete
如果文件不存在不会抛异常
在文件夹中创建文件
Directory.CreateDirectory + File.WriteAllText
保证文件夹存在
用 FileInfo 操作
new FileInfo(path).Create / Delete / Exists
用于多次操作

10. Common errors when working with files

错误 №1: 忘记在 File.Create 之后关闭流。
很多新手用 File.Create 创建文件,但不关闭返回的流。结果后面的代码就“看不到”文件了——好像掉进了平行宇宙。要显式关闭流(Close())或用 using

错误 №2: 试图在不存在的文件夹里创建文件。
常见的坑是试图在还没创建的目录里建文件。别忘了提前调用 Directory.CreateDirectory。这是绝对安全的:不会多创建什么,必要的文件夹会出现。

错误 №3: 在删除前不检查。
有时人们直接调用 File.Delete,不检查文件是否存在。这个方法在文件不存在时不会报错,但如果路径写错或没有权限 — 异常是会发生的。最好提前处理这些情况。

错误 №4: 混淆 File.DeleteDirectory.Delete
File.Delete 只对文件有效,Directory.Delete 用于目录。用 File.Delete 去删目录就像用牙刷去抛光砖块:技术上可能搞不定,但并不合适。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION