千家信息网

C#中文件操作、读取文件、Debug/Trace类的示例分析

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要为大家展示了"C#中文件操作、读取文件、Debug/Trace类的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"C#中文件操作、读取文
千家信息网最后更新 2026年11月02日C#中文件操作、读取文件、Debug/Trace类的示例分析

这篇文章主要为大家展示了"C#中文件操作、读取文件、Debug/Trace类的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"C#中文件操作、读取文件、Debug/Trace类的示例分析"这篇文章吧。

1、文件操作

这段代码在 System.Private.CoreLib 下,对 System.IO.File 中的代码进行精简,供 CLR 使用。

当使用文件时,要提前判断文件路径是否存在,日常项目中要使用到文件的地方应该不少,可以统一一个判断文件是否存在的方法:

        public static bool Exists(string? path)        {            try            {                // 可以将 string? 改成 string                if (path == null)                    return false;                if (path.Length == 0)                    return false;                path = Path.GetFullPath(path);                // After normalizing, check whether path ends in directory separator.                // Otherwise, FillAttributeInfo removes it and we may return a false positive.                // GetFullPath should never return null                Debug.Assert(path != null, "File.Exists: GetFullPath returned null");                if (path.Length > 0 && PathInternal.IsDirectorySeparator(path[^1]))                {                    return false;                }                return InternalExists(path);            }            catch (ArgumentException) { }            catch (NotSupportedException) { } // Security can throw this on ":"            catch (SecurityException) { }            catch (IOException) { }            catch (UnauthorizedAccessException) { }            return false;        }

建议项目中对路径进行最终处理的时候,都转换为绝对路径:

Path.GetFullPath(path)

当然,相对路径会被 .NET 正确识别,但是对于运维排查问题和各方面考虑,绝对路径容易定位具体位置和排错。

在编写代码时,使用相对路径,不要写死,提高灵活性;在运行阶段将其转为绝对路径;

上面的 NotSupportedException 等异常是操作文件中可能出现的各种异常情况,对于跨平台应用来说,这些异常可能都是很常见的,提前将其异常类型识别处理,可以优化文件处理逻辑以及便于筛查处理错误。

2、读取文件

这段代码在 System.Private.CoreLib 中。

有个读取文件转换为 byte[] 的方法如下:

        public static byte[] ReadAllBytes(string path)        {            // bufferSize == 1 used to avoid unnecessary buffer in FileStream            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1))            {                long fileLength = fs.Length;                if (fileLength > int.MaxValue)                    throw new IOException(SR.IO_FileTooLong2GB);                int index = 0;                int count = (int)fileLength;                byte[] bytes = new byte[count];                while (count > 0)                {                    int n = fs.Read(bytes, index, count);                    if (n == 0)                        throw Error.GetEndOfFile();                    index += n;                    count -= n;                }                return bytes;            }        }

可以看到 FileStream 的使用,如果单纯是读取文件内容,可以参考里面的代码:

        FileStream fs = new FileStream(path,                                        FileMode.Open,                                        FileAccess.Read,                                        FileShare.Read,                                        bufferSize: 1)

上面的代码同样也存在 File.ReadAllBytes 与之对应, File.ReadAllBytes 内部是使用 InternalReadAllBytes 来处理文档读取:

        private static byte[] InternalReadAllBytes(String path, bool checkHost)        {            byte[] bytes;            // 此 FileStream 的构造函数不是 public ,开发者不能使用            using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,                 FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, checkHost)) {                // Do a blocking read                int index = 0;                long fileLength = fs.Length;                if (fileLength > Int32.MaxValue)                    throw new IOException(Environment.GetResourceString("IO.IO_FileTooLong2GB"));                int count = (int) fileLength;                bytes = new byte[count];                while(count > 0) {                    int n = fs.Read(bytes, index, count);                    if (n == 0)                        __Error.EndOfFile();                    index += n;                    count -= n;                }            }            return bytes;        }

这段说明我们可以放心使用 File 静态类中的函数,因为里面已经处理好一些逻辑了,并且自动释放文件。

如果我们手动 new FileStream ,则要判断一些情况,以免使用时报错,最好参考一下上面的代码。

.NET 文件流缓存大小默认是 4096 字节:

internal const int DefaultBufferSize = 4096;

这段代码在 File 类中定义,开发者不能设置缓存块的大小,大多数情况下,4k 是最优的块大小。

ReadAllBytes 的文件大小上限是 2 GB。

3、Debug 、Trace类

这两个类的命名空间为 System.Diagnostics,Debug 、Trace 提供一组有助于调试代码的方法和属性。

Debug 中的所有函数都不会在 Release 中有效,并且所有输出流不会在控制台显示,必须注册侦听器才能读取这些流。

Debug 可以打印调试信息并使用断言检查逻辑,使代码更可靠,而不会影响发运产品的性能和代码大小。

这类输出方法有 Write 、WriteLine 、 WriteIf 和 WriteLineIf 等,这里输出不会直接打印到控制台。

如需将调试信息打印到控制台,可以注册侦听器:

ConsoleTraceListener console = new ConsoleTraceListener();Trace.Listeners.Add(console);

注意, .NET Core 2.x 以上 Debug 没有 Listeners ,因为 Debug 使用的是 Trace 的侦听器。

我们可以给 Trace.Listeners 注册侦听器,这样相对于 Debug 等效设置侦听器。

        Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));        Debug.WriteLine("aa");

.NET Core 中的监听器都继承了 TraceListener,如 TextWriterTraceListener、ConsoleTraceListener、DefaultTraceListener。

如果需要输出到文件中,可以自行继承 TextWriterTraceListener ,编写文件流输出,也可以使用 DelimitedListTraceListener。

示例:

TraceListener listener = new DelimitedListTraceListener(@"C:\debugfile.txt");        // Add listener.        Debug.Listeners.Add(listener);        // Write and flush.        Debug.WriteLine("Welcome");

处理上述方法输出控制台,也可以使用

ConsoleTraceListener console=......Listeners.Add(console);// 等效于var console = new TextWriterTraceListener(Console.Out)

为了格式化输出流,可以使用 一下属性控制排版:

属性说明
AutoFlush获取或设置一个值,通过该值指示每次写入后是否应在 Flush() 上调用 Listeners。
IndentLevel获取或设置缩进级别。
IndentSize获取或设置缩进的空格数。
        // 1.        Debug.WriteLine("One");        // Indent and then unindent after writing.        Debug.Indent();        Debug.WriteLine("Two");        Debug.WriteLine("Three");        Debug.Unindent();        // End.        Debug.WriteLine("Four");        // Sleep.        System.Threading.Thread.Sleep(10000);
One    Two    ThreeFour

.Assert() 方法对我们调试程序很有帮助,Assert 向开发人员发送一个强消息。在 IDE 中,断言会中断程序的正常操作,但不会终止应用程序。

.Assert() 的最直观效果是输出程序的断言位置。

        Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));        int value = -1;        // A.        // If value is ever -1, then a dialog will be shown.        Debug.Assert(value != -1, "Value must never be -1.");        // B.        // If you want to only write a line, use WriteLineIf.        Debug.WriteLineIf(value == -1, "Value is -1.");
---- DEBUG ASSERTION FAILED -------- Assert Short Message ----Value must never be -1.---- Assert Long Message ----   at Program.Main(String[] args) in ...Program.cs:line 12Value is -1.

Debug.Prinf() 也可以输出信息,它跟 C 语言的 printf 函数行为一致,将后跟行结束符的消息写入,默认行终止符为回车符后跟一个换行符。

在 IDE 中运行程序时,使用 Debug.Assert()、Trace.Assert() 等方法 ,条件为 false 时,IDE 会断言,这相当于条件断点。

在非 IDE 环境下,程序会输出一些信息,但不会有中断效果。

        Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));        Trace.Assert(false);
Process terminated. Assertion Failed   at Program.Main(String[] args) in C:\ConsoleApp4\Program.cs:line 44

个人认为,可以将 Debug、Trace 引入项目中,与日志组件配合使用。Debug、Trace 用于记录程序运行的诊断信息,便于日后排查程序问题;日志用于记录业务过程,数据信息等。

.Assert() 的原理, 在 true 时什么都不做;在 false 时调用 Fail 函数;如果你不注册侦听器的话,默认也没事可做。

.Assert() 唯一可做的事情是等条件为 false 时,执行 Fail 方法,当然我们也可以手动直接调用 Fail 方法,Fail 的代码如下:

public static void Fail(string message) {            if (UseGlobalLock) {                lock (critSec) {                    foreach (TraceListener listener in Listeners) {                        listener.Fail(message);                        if (AutoFlush) listener.Flush();                    }                            }            }            else {                foreach (TraceListener listener in Listeners) {                    if (!listener.IsThreadSafe) {                        lock (listener) {                            listener.Fail(message);                            if (AutoFlush) listener.Flush();                        }                    }                    else {                        listener.Fail(message);                        if (AutoFlush) listener.Flush();                    }                }                        }        }

以上是"C#中文件操作、读取文件、Debug/Trace类的示例分析"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

文件 代码 输出 方法 程序 路径 侦听器 信息 处理 函数 大小 控制 示例 内容 控制台 C# 分析 属性 情况 条件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中智农互联网科技 科技与互联网 狮子座互联网科技 奇酷互联网科技 南京欣网互联网科技 互联网科技上市公司 金融科技和互联网金融 互联网科技类展会 中盈科技互联网信息有限公司 深圳国际航运科技和互联网 创业天下互联网科技有限公司 银川新华互联网科技学校联系电话 本届互联网博览会上的黑科技 朱啸虎曾投资哪些互联网科技企业 世界互联网领先科技成果获奖 区块链结合互联网科技 浙南科技城互联网大厦招聘 萌小萌互联网科技河南有限公司 福州德业互联网科技 现代科技的标志之一的互联网 互联网属科技 互联网最新的科技有限公司 科技伦理 互联网公司 卫星互联网科技股票 北京华百购互联网科技有限公司 互联网行业科技股 上海钢联属于互联网科技股吗 抖集互联网科技技术咨询 广西泛欧互联网科技有限公司 互联网科技自媒体灵感
0