广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#文件操作、读取文件、Debug/Trace类用法
  • 202
分享到

C#文件操作、读取文件、Debug/Trace类用法

2024-04-02 19:04:59 202人浏览 独家记忆
摘要

1、文件操作 这段代码在 System.Private.CoreLib 下,对 System.io.File 中的代码进行精简,供 CLR 使用。 当使用文件时,

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
    Three
Four

.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 12

Value 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类用法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: C#文件操作、读取文件、Debug/Trace类用法

本文链接: https://www.lsjlt.com/news/144218.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#文件操作、读取文件、Debug/Trace类用法
    1、文件操作 这段代码在 System.Private.CoreLib 下,对 System.IO.File 中的代码进行精简,供 CLR 使用。 当使用文件时,...
    99+
    2022-11-13
  • C#中文件操作、读取文件、Debug/Trace类的示例分析
    这篇文章主要为大家展示了“C#中文件操作、读取文件、Debug/Trace类的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#中文件操作、读取文件、Debug/Trace类的示例分析”...
    99+
    2023-06-29
  • C#读取文件的方法
    本篇内容介绍了“C#读取文件的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!C#读取文件高效方法问题的提出:你平时是怎么读取文件的?使用...
    99+
    2023-06-18
  • C#使用StreamReader和StreamWriter类读写操作文件
    StreamReader 类 (System.IO) | Microsoft 官方文档 StreamWriter 类 (System.IO) | Microsoft 官方文档 一、文...
    99+
    2022-11-13
  • C++文件读写操作详解
    目录一、读写文本文件1.1 写文件1.2读文件二、读写二进制文件2.1 写文件2.2 读文件一、读写文本文件 1.1 写文件 写文件步骤如下: 包含头文件 #include <...
    99+
    2022-11-13
  • C#文件读写操作 [详细]
    C#文件读写操作 C# 中的 I/O 类FileStream 类C#中文本文件的读取写入1) StreamReader2) StreamWriter 二进制文件读写1) BinaryRe...
    99+
    2023-09-09
    c# 开发语言 java
  • C#怎么使用StreamReader和StreamWriter类读写操作文件
    这篇文章主要讲解了“C#怎么使用StreamReader和StreamWriter类读写操作文件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#怎么使用StreamReader和Strea...
    99+
    2023-06-30
  • java io文件操作从文件读取数据的六种方法
    目录1.Scanner2.Files.lines (Java 8)3.Files.readAllLines4.Files.readString(JDK 11)5.Files.read...
    99+
    2022-11-13
  • python3 文件的读取和通用操作
    import os           # 当前操作目录,os.chdir() 切换操作目录 >>> import os >>> os.getcwd() 'C:\\ProgramFiles\\Pyth...
    99+
    2023-01-31
    操作 文件
  • C#文件非占用读取与帮助类FileHelper
    非占用方式: FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.R...
    99+
    2022-11-13
  • Python3读取文件的操作详解
    目录1、引言2、 fileinput2.1 方法介绍2.2 默认读取2.3 处理一个文件2.4 处理批量文件2.5 读取与备份2.5 重定向替换2.6 进阶3、总结1、引言 小鱼:小...
    99+
    2022-11-11
  • SpringBoot读取yaml文件操作详解
    目录1. 单个属性2. 全部属性3. 对象属性补充1. 单个属性 yaml 内的属性如下: server: port: 80 只需在成员变量上注解 @Value(“...
    99+
    2022-11-13
  • 怎么用C#读取Excel文件
    这篇文章主要讲解了“怎么用C#读取Excel文件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用C#读取Excel文件”吧!C#读取Excel文件方法一:直接读取(这种直接读取单元格的方...
    99+
    2023-06-18
  • C++文件流读写操作详解
    目录1.打开文件1.1 fstream类型1.2 open()的函数原型1.3 打开方式1.4 打开文件的属性1.5 示例代码2.文本文件的读写2.1 写文件示例2.2 读文件示例2...
    99+
    2022-11-12
  • C++中TinyXML读取xml文件用法详解
    目录前言XML文件理解常用的XML类方法使用总结前言 TinyXML下载地址:https://sourceforge.net/projects/tinyxml/ 官方文档:TinyX...
    99+
    2022-11-13
  • Go读取文件与写入文件的三种方法操作指南
    目录文件写入操作Write和WriteString写入操作使用buffio内置包来读文件第三种写入文件方法:ioutil.WriteFile总结打开和关闭文件操作: os.Open(...
    99+
    2022-11-11
  • c语言怎么操作文件的读取和写入
    这篇文章主要介绍“c语言怎么操作文件的读取和写入”,在日常操作中,相信很多人在c语言怎么操作文件的读取和写入问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”c语言怎么操作文件的读取和写入”的疑惑有所帮助!接下来...
    99+
    2023-06-20
  • 【Python】文件操作 ③ ( 文件操作 | 使用 for 循环读取文件 | 使用 close 函数关闭文件 | with open 语法自动处理文件关闭 )
    文章目录 一、读取文件1、使用 for 循环读取文件 二、关闭文件1、close 函数2、代码示例 - 文件被占用3、代码示例 - 关闭文件 三、with open 语法自动处理文件关...
    99+
    2023-10-26
    python 开发语言 关闭文件 PyCharm with open 原力计划
  • android文件操作——读取assets和raw文件下的内容
    来自Resources和Assets 中的文件只可以读取而不能进行写的操作。 assets文件夹里面的文件都是保持原始的文件格式,需要用AssetManager以字节流的形式...
    99+
    2022-06-06
    raw文件 Android
  • 使用BufferedReader读取本地文件的操作
    BufferedReader读取本地文件 在使用BufferedWriter写入文件时,如果忘记关闭文件(close)同时也没有调用flush(),则被写入的文件中是没有内容的。 在...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作