CodeGym /课程 /C# SELF /文件打开模式

文件打开模式

C# SELF
第 35 级, 课程 4
可用

1. 入门

当你用FileStream或者其他流类操作文件时,提前搞清楚打开文件会发生啥特别重要。经常会遇到文件已经存在的情况,这时你可能想往文件后面加新内容但不丢旧的,或者直接把文件整个覆盖掉。还有的时候,文件还没创建,你只想读它,但又不想误操作生成一个空文件。

比如,你写一个日记本,目标就是把新内容追加到已有文件末尾,保留之前写的所有东西。这就得用追加模式打开文件。再比如,你有个日志文件,每次程序启动都要重新生成,避免旧数据干扰。这时就要用能清空或新建文件的模式。如果你只是想读文件,肯定不希望没文件时自动新建一个空的,不然本来没文件的地方就多了个空文件。

这些不同的场景——追加、覆盖、只读不创建——在C#里都是通过System.IO.FileMode枚举的各种模式来实现的。每种模式都控制着打开或创建文件时的行为,让你能精确掌控文件操作时会发生什么。

2. FileMode枚举——通俗讲解

下面是FileMode枚举的主要取值:

取值 说明 文件已存在时 文件不存在时
CreateNew
新建文件。如果文件已经存在——抛出异常 报错 OK,文件被创建
Create
如果没有就新建,有的话覆盖原文件 覆盖 OK,新建
Open
打开已存在的文件。没有文件时——异常 OK,打开 报错
OpenOrCreate
有就打开,没有就新建 OK,打开 OK,新建
Truncate
打开已存在文件并清空内容(长度变0) OK,清空文件 报错
Append
打开文件追加内容到末尾,没有就新建 OK,追加到末尾 OK,新建

图解:各种场景下的行为


flowchart TD
    Start[开始]
    A{文件存在吗?}
    B1[打开追加]
    B2[新建文件]
    B3[覆盖文件]
    B4[打开文件]
    B5[错误:找不到文件]
    B6[错误:文件已存在]

    Start --> A
    A --Append, OpenOrCreate--> B1
    A --Create, Truncate--> B3
    A --Open, Truncate--> B4
    A --CreateNew--> B6
    A --Create, OpenOrCreate, Append--> B2
    A --Open, Truncate--> B5
FileMode各种模式下的行为场景

3. 不同模式下的文件打开例子

来点实操,假设我们有个文本文件,往里写问候语和日期。我们看三个常见场景:

  • A. 新建文件(CreateNew)
  • B. 覆盖文件(Create)
  • C. 追加内容到文件末尾(Append)

新建文件(FileMode.CreateNew)

如果文件已经存在,这个模式保证不会重新创建:程序会抛出IOException异常。适合不能丢数据或不想误删别人文件的场景。

using System;
using System.IO;

string filePath = "greeting.txt";

// 尝试新建文件——如果已存在会抛异常!
try
{
    var stream = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write);
    var writer = new StreamWriter(stream);
    
    writer.WriteLine("你好!这是第一条记录。");
    writer.WriteLine($"日期:{DateTime.Now}");
    
    Console.WriteLine("文件创建成功。");   
    writer.Close();
}
catch (IOException)
{
    Console.WriteLine($"文件 '{filePath}' 已经存在!不覆盖它。");
}

注意:如果你第二次运行这段代码——会进入catch,数据不会被覆盖。

覆盖文件(FileMode.Create)

这个模式很直接:有文件就清空,没有就新建。适合每次都要“从头开始”的场景,比如重保存报告。

using System;
using System.IO;

string filePath = "greeting.txt";

// 新建或完全覆盖文件
var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
var writer = new StreamWriter(stream);

writer.WriteLine("你好!我把文件完全更新了 :)");
writer.WriteLine($"已更新:{DateTime.Now}");

Console.WriteLine("文件已创建或覆盖。");
writer.Close();

多运行几次这段代码——文件里永远只有最新的内容,旧的全没了。

追加内容到文件末尾(FileMode.Append)

这个模式超适合日志、事件记录、访问统计等场景。没有文件就新建,有的话内容加到末尾。

using System;
using System.IO;

string filePath = "greeting.txt";

// 在文件末尾追加新内容
var stream = new FileStream(filePath, FileMode.Append, FileAccess.Write);
var writer = new StreamWriter(stream);

writer.WriteLine($"又一条问候!日期:{DateTime.Now}");

Console.WriteLine("新内容已追加到文件末尾。");
writer.Close();

多次运行这段代码,文件会越来越大,每次新内容都在最后。

4. 怎么选文件打开模式?实用建议

真实场景举例:

  • 日志:几乎总是用Append。日志被覆盖管理员会心痛,坏人会偷笑。
  • 导出报告:一般用Create,避免文件夹里堆一堆旧版本。
  • 关键数据导出:用CreateNew。有文件就报错,啥都不动。
  • 读文件:根本不用创建模式,直接用FileMode.Open——没文件就说明有问题。

写C#代码时,经常用File类的静态方法,它们内部会自动选合适的模式。比如File.AppendAllText总是用Append,File.WriteAllText用Create。

5. 文件模式和常见坑

有点小陷阱要注意:

用FileMode.Create或FileMode.Truncate打开文件时,内容会被清空。小心点——数据丢失不仅新手会遇到,老程序员也踩过坑。

用FileMode.Open或FileMode.Truncate打开不存在的文件,会抛FileNotFoundException。记得用File.Exists(path)先检查文件在不在。

Append模式只能写,不能读。如果你要读写都能用,考虑用其他模式(OpenOrCreate加合适的FileAccess)。

例子:读写文件

有时候你既想读又想写(比如开个银行账户——要存钱也要查余额)。用FileMode.OpenOrCreate:

using System.IO;

string filePath = "balance.txt";

// 读写打开文件,没有就新建
var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
// 这里可以读也可以写

6. 实用细节

文件打开模式流程


graph TD
    A[请求文件] --> B[选择模式]
    B --> C1[CreateNew] -->|如果文件存在| D1[错误]
    C1 -->|文件不存在| E1[新建]
    B --> C2[Create] -->|总是| F1[新建/覆盖]
    B --> C3[Open] -->|文件存在| G1[打开]
    C3 -->|文件不存在| D1
    B --> C4[OpenOrCreate] -->|文件存在| G1
    C4 -->|文件不存在| E1
    B --> C5[Append] -->|文件存在| H1[打开追加]
    C5 -->|文件不存在| E1
    B --> C6[Truncate] -->|文件存在| I1[清空]
    C6 -->|文件不存在| D1
文件打开模式选择流程图

文件打开模式对比表

FileMode 文件存在 文件不存在 数据访问 会清空旧内容吗?
CreateNew
异常 新建 写 不适用
Create
覆盖 新建 写 是
Open
打开 异常 读/写 否
OpenOrCreate
打开 新建 读/写 否
Truncate
清空 异常 写 是
Append
打开追加 新建 只能写 否(追加)

和File类高级方法的对比

  • File.WriteAllText(path, text) → 内部用FileMode.Create,也就是会覆盖旧文件。
  • File.AppendAllText(path, text) → 用Append,内容都加到末尾。
  • File.ReadAllText(path) → 以只读模式打开(FileMode.Open)。

有时候这些方法就够了,但用FileStream加上明确的模式能让你完全掌控文件操作。

不同操作系统下的注意点

很多开发者没注意到,在Windows下,如果一个文件被别的进程以写方式打开,再次打开会报错。所以要合理用FileShare参数,控制文件的共享访问(后面会专门讲)。不同系统的锁和权限机制可能不一样,但文件打开模式的原理是通用的。

1
调查/小测验
文件操作第 35 级,课程 4
不可用
文件操作
C#中文件操作基础
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION