unity的C#学习——预处理指令、异常处理和文件的输入输出

这篇具有很好参考价值的文章主要介绍了unity的C#学习——预处理指令、异常处理和文件的输入输出。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


预处理器指令

C# 中的预处理器指令是用来指示编译器在编译代码之前执行一些预处理操作的特殊指令。预处理器指令以井号 # 开始,并且必须出现在代码的最外层,不能包含在方法或类的内部。


1、#define

#define 指令用于定义一个符号常量。符号常量可以在代码中使用 #if#elif 指令进行条件编译。例如:

#define DEBUG
#if DEBUG
    Console.WriteLine("Debug mode is enabled.");
#endif

在上面的示例中,我们使用 #define 指令定义了一个名为 DEBUG 的符号常量。然后在 #if 指令中,根据 DEBUG 符号常量是否已定义(定义判定为true,未定义判定为false)来编译代码块。


2、#undef

#undef 指令用于取消已定义的符号常量。例如:

#define DEBUG
#if DEBUG
    Console.WriteLine("Debug mode is enabled.");
#endif

#undef DEBUG
#if DEBUG
    Console.WriteLine("Debug mode is still enabled.");
#endif

在上面的示例中,我们首先使用 #define 指令定义了一个名为 DEBUG 的符号常量。然后在 #if 指令中,根据 DEBUG 符号常量是否已定义来编译代码块。接着使用 #undef 指令取消了 DEBUG 符号常量的定义,再次使用 #if 指令来编译代码块。


3、#if, #elif, #else, #endif

  • #if 指令用于根据符号常量是否已定义来编译代码块。如果符号常量已定义,则编译代码块。

例如:

#define DEBUG
#if DEBUG
    Console.WriteLine("Debug mode is enabled.");
#endif
  • #elif 指令在 #if 指令中添加一个新的条件。如果之前的条件不成立,且当前条件成立,则编译代码块。
  • #else 指令在 #if#elif 指令中添加一个默认条件。如果之前的条件不成立,则编译代码块。
  • #endif 指令用于结束一个 #if#elif 块。

例如:

#define DEBUG
#if DEBUG
    Console.WriteLine("Debug mode is enabled.");
#elif RELEASE
    Console.WriteLine("Release mode is enabled.");
#else
    Console.WriteLine("Unknown mode is enabled.");
#endif

3.1 条件指令

我们可以使用 #if 指令来创建一个条件指令,该指令用于测试符号是否为真(即符号常量是否用#define定义)。如果为真,编译器会执行 #if 和下一个指令之间的代码。

条件指令的语法:

#if symbol [operator symbol]...
  • 其中symbol 是要测试的符号常量,我们也可以使用 truefalse,或在符号前放置否定运算符"!"
  • 常见运算符有:== (等于)!= (不等于)&& (与)|| (或)
  • 我们也可以用括号把符号和运算符进行分组。

条件指令用于在调试版本或编译指定配置时编译代码。一个以 #if 指令开始的条件指令,必须显示地以一个 #endif 指令终止。下面的程序演示了条件指令的用法:

#define DEBUG
#define VC_V10
using System;
public class TestClass
{
   public static void Main()
   {

      #if (DEBUG && !VC_V10)
         Console.WriteLine("DEBUG is defined");
      #elif (!DEBUG && VC_V10)
         Console.WriteLine("VC_V10 is defined");
      #elif (DEBUG && VC_V10)
         Console.WriteLine("DEBUG and VC_V10 are defined");
      #else
         Console.WriteLine("DEBUG and VC_V10 are not defined");
      #endif
      Console.ReadKey();
   }
}

当上面的代码被编译和执行时,它会产生下列结果:

DEBUG and VC_V10 are defined


4、#warning, #error

  • #warning 指令用于输出一个编译器警告。例如:
#if RELEASE
	#warning This code needs to be refactored.
  • #error 指令用于输出一个编译器错误。例如:
#if RELEASE
    #error This code needs to be refactored.

5、#region, #endregion

  • #region 指令用于将代码块分组,并可以为其命名。
  • #endregion 指令用于结束一个 #region 块。

例如:

#region MyRegion
    Console.WriteLine("This code is in MyRegion.");
#endregion

在 Visual Studio 编辑器中,可以使用加号展开或减号折叠一个 #region 块。


6、#pragma

#pragma 指令用于向编译器发送特定的指令。例如:

#pragma warning disable
    // some code
#pragma warning restore

在上面的示例中,#pragma warning disable 指令告诉编译器禁用所有警告,#pragma warning restore 指令告诉编译器恢复之前的警告设置。


7、#nullable

#nullable 指令用于为整个文件或特定作用域启用或禁用可空引用类型。例如:

#nullable enable
    string? name = null;
    Console.WriteLine(name.Length); // warning CS8602
#nullable disable
    string? name = null;
    Console.WriteLine(name.Length); // no warning

在上面的示例中,#nullable enable 指令启用可空引用类型检查,#nullable disable 指令禁用可空引用类型检查。


8、#pragma warning

#pragma warning 指令用于设置编译器警告的级别禁用/启用特定的警告。例如:

// 禁用编译器警告 CS0219(变量未使用)
#pragma warning disable CS0219
    int unused = 0;
// 恢复编译器警告 CS0219
#pragma warning restore CS0219

// 禁用编译器警告 CS8602(可能的空引用异常)
#pragma warning disable CS8602
    string? name = null;
    Console.WriteLine(name.Length); // 不会出现警告
// 恢复编译器警告 CS8602
#pragma warning restore CS8602

// 抑制编译器警告 CS8600(空引用检查可能不准确)
#pragma warning suppress CS8600
    string? name = null;
    Console.WriteLine(name.Length); // 警告 CS8602

在上面的示例中,#pragma warning disable 指令禁用特定警告,#pragma warning restore 指令恢复之前的警告设置,#pragma warning suppress 指令抑制特定警告。


异常处理

异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。

在C#中,异常处理是通过捕获并处理异常对象来处理运行时错误的过程。在执行程序时,如果发生异常,程序会停止执行,并且会生成一个异常对象。如果不对异常进行处理,程序将会崩溃。

C#提供了一组关键字和语法结构,用于捕获和处理异常。以下是一些常见的异常处理关键字和语法:


1、try-catch语句

try-catch语句用于捕获和处理异常。在try块中编写可能会抛出异常的代码,在catch块中编写处理异常的代码。如果try块中的代码引发异常,程序将会跳转到catch块中,执行相应的异常处理代码。

以下是try-catch语句的基本语法:

try
{
    // 可能会抛出异常的代码
}
catch (Exception ex)
{
    // 处理异常的代码
}

2、finally块

finally块用于编写无论是否发生异常都需要执行的代码。在finally块中编写的代码将在try块或catch块执行完毕后执行。

以下是finally块的基本语法:

try
{
    // 可能会抛出异常的代码
}
catch (Exception ex)
{
    // 处理异常的代码
}
finally
{
    // 无论是否发生异常都需要执行的代码
}
  • 如果在try-catch语句中添加了return语句,finally块会在return语句执行之前执行。

这是因为finally块中的代码是在try-catch块中的所有代码执行完成后执行的,而return语句会立即结束当前方法的执行并返回结果,因此finally块中的代码会在return语句执行之前被执行。以下是一个示例:

public int DoSomething()
{
    try
    {
        // 可能会抛出异常的代码
        return 1;
    }
    catch (Exception ex)
    {
        // 处理异常的代码
        return 0;
    }
    finally
    {
        // 无论是否发生异常都需要执行的代码
        Console.WriteLine("finally block executed.");
    }
}

在上面的示例中,如果try块中的代码没有抛出异常,将返回值1,并且finally块中的代码将被执行。如果try块中的代码抛出了异常,将返回值0,并且finally块中的代码也将被执行。无论是哪种情况,finally块中的代码都会在返回结果之前执行。


3、throw语句

throw语句用于在程序中抛出一个异常对象。当程序执行到throw语句时,程序将停止执行,并将控制权转移到最近的catch块

以下是throw语句的基本语法:

throw new Exception("错误消息");

4、内置的异常类

在C#中,异常类是用于处理程序中出现的错误情况的类。当程序运行时出现异常,会创建一个异常对象,其中包含有关异常情况的信息,例如异常类型、消息、堆栈跟踪和其他有用的调试信息。开发人员可以使用C#中的异常类来处理异常,以便使程序在出现异常时能够更加可靠地运行和恢复。

在C#中,常见的异常类包括:

序号 异常类名 描述
1 System.Exception 所有异常的基类。
2 System.ApplicationException 用户自定义异常类应该派生自此类。
3 System.ArgumentException 表示参数错误异常。
4 System.ArgumentNullException 表示参数为 null 的异常。
5 System.ArgumentOutOfRangeException 表示参数超出范围的异常。
6 System.ArrayTypeMismatchException 表示数组类型不匹配的异常。
7 System.DivideByZeroException 表示除数为零的异常。
8 System.IndexOutOfRangeException 表示索引超出范围的异常。
9 System.IO.IOException 表示输入输出错误的异常。
10 System.InvalidCastException 表示类型转换无效的异常。
11 System.NullReferenceException 表示对象为 null 的异常。
12 System.OutOfMemoryException 表示内存不足的异常。
13 System.StackOverflowException 表示堆栈溢出的异常。

这些异常类提供了许多属性和方法,以便开发人员能够识别、记录和处理异常。

  • 开发人员可以在catch语句内指定需要捕获和处理异常类;
  • 还可以使用throw语句在代码中显式地引发异常。

以下是一个示例:

using System

try
{
    // 可能会抛出异常的代码
}
catch (ArgumentNullException ex)
{
    // 处理参数为null的异常,可以通过对象ex输出异常类型
}
catch (Exception ex)
{
    // 处理其他类型的异常,可以通过对象ex输出异常类型
}
finally
{
    // 无论是否发生异常都需要执行的代码
}

在上面的示例中,try块中的代码可能会抛出异常。如果抛出的异常类型是ArgumentNullException,则会执行第一个catch块中的代码;如果是其他类型的异常,则会执行第二个catch块中的代码。无论是否发生异常,finally块中的代码都将被执行。


5、自定义异常类

在C#中,可以定义自己的异常类,以便更好地描述程序中发生的错误。用户自定义异常类可以派生自System.Exception类,也可以派生自ApplicationException类,它们都提供了一些方法和属性,用于处理和描述异常。

  • ApplicationException 类是 System.Exception 类的一个子类,它在 .NET Framework 1.1中引入,旨在提供一种更好的异常处理方法。
  • 不过随着 .NET Framework 2.0的发布,微软官方建议开发者不再使用ApplicationException类来派生自定义异常类,而是直接从 System.Exception 派生。这是因为在 .NET Framework 2.0及以后的版本中,ApplicationException 类没有提供额外的功能,与 System.Exception 类没有什么区别。

在使用自定义异常类时,可以使用throw语句抛出自定义异常对象。以下是自定义异常类的基本语法:

using System

// 自定义异常类,继承基类Exception
public class MyException : Exception
{
    public MyException(string message) : base(message)
    {
    	throw new MyException("错误消息");
    }
}

文件的输入输出

一个文件是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:

  • 输入流:用于从文件读取数据(读操作)。
  • 输出流:用于向文件写入数据(写操作)。

1、I/O 相关类列举

在C#的System.IO 命名空间中有各种不同的类,用于执行各种文件的输入输出操作,如创建和删除文件、读取或写入文件,关闭文件等。

下表列出了一些 System.IO 命名空间中常用的非抽象类

序号 I/O 类 描述
1 BinaryReader 从二进制流读取原始数据。
2 BinaryWriter 以二进制格式写入原始数据。
3 BufferedStream 字节流的临时存储。
4 Directory 有助于操作目录结构。
5 DirectoryInfo 用于对目录执行操作。
6 DriveInfo 提供驱动器的信息。
7 File 有助于处理文件。
8 FileInfo 用于对文件执行操作。
9 FileStream 用于文件中任何位置的读写。
10 MemoryStream 用于随机访问存储在内存中的数据流。
11 Path 对路径信息执行操作。
12 StreamReader 用于从字节流中读取字符。
13 StreamWriter 用于向一个流中写入字符。
14 StringReader 用于读取字符串缓冲区。
15 StringWriter 用于写入字符串缓冲区。

2、FileStream 类

System.IO 命名空间中的 FileStream 类有助于文件的读写与关闭。该类派生自抽象类 Stream

我们需要通过创建一个 FileStream 对象来创建一个新的文件,或打开一个已有的文件。创建 FileStream 对象的语法如下:

FileStream <object_name> = new FileStream( <file_name>, <FileMode Enumerator>, <FileAccess Enumerator>, <FileShare Enumerator>);
参数 描述
FileMode FileMode 枚举类型定义了打开文件的不同方式。FileMode 枚举的成员有:

Append:打开一个已有的文件,并将光标放置在文件的末尾。如果文件不存在,则创建文件。
Create:创建一个新的文件。如果文件已存在,则删除旧文件,然后创建新文件。
CreateNew:指定操作系统应创建一个新的文件。如果文件已存在,则抛出异常。
Open:打开一个已有的文件。如果文件不存在,则抛出异常。
OpenOrCreate:指定操作系统应打开一个已有的文件。如果文件不存在,则用指定的名称创建一个新的文件打开。
Truncate:打开一个已有的文件,文件一旦打开,就将被截断为零字节大小。然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期。如果文件不存在,则抛出异常。
FileAccess FileAccess 枚举类型定义了文件的访问模式,FileAccess 枚举的成员有:

Read:表示以只读方式打开文件,不允许写入文件。
Write:表示以只写方式打开文件,不允许读取文件。
ReadWrite:表示以读写方式打开文件,既可以读取也可以写入文件。
FileShare FileShare 枚举类型定义了文件的共享模式,FileShare 枚举的成员有:

Inheritable:允许文件句柄可由子进程继承。Win32 不直接支持此功能。
None:不允许其他进程访问该文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。
Read:允许其他进程以只读方式访问该文件。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
ReadWrite:允许其他进程以读写方式访问该文件。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
Write:允许其他进程以只写方式访问该文件。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
Delete:允许其他进程删除该文件。这意味着如果一个进程以此参数打开了一个文件,它可以在文件关闭前删除该文件。如果其他进程正在写入该文件,则会出现冲突。

例如,创建一个 FileStream 对象 F 来读取名为 sample.txt 的文件:

FileStream F = new FileStream("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
  • File.OpenSystem.IO命名空间中的静态方法,可以用于打开一个文件并返回一个FileStream对象,它提供了对文件的基本操作。

使用File.Open方法时,需要指定文件名、打开方式、访问权限等参数,如上例也可写成:

FileStream F = File.Open("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);

下面的程序详细演示了 FileStream 类的用法:

using System;
using System.IO;

namespace FileIOApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个FileStream对象来打开一个文件test.dat,以进行读写操作
            // 如果文件不存在,则创建新文件;如果文件已经存在,则打开文件进行读写
            FileStream F = new FileStream("test.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite);

            // 写入20个字节到文件中
            for (int i = 1; i <= 20; i++)
            {
                F.WriteByte((byte)i);
            }

            // 重置流的位置到文件开头
            F.Position = 0;

            // 读取文件中的每个字节,并打印到控制台
            for (int i = 0; i <= 20; i++)
            {
                Console.Write(F.ReadByte() + " ");
            }

            // 关闭文件流
            F.Close();

            // 等待用户按下一个键继续
            Console.ReadKey();
        }
    }
}

当上面的代码被编译和执行时,它会产生下列结果:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1


2、StreamReader 和 StreamWriter 类

在C#中,StreamReader 类和 StreamWriter 类都是用于读取和写入文本文件的类。

  • StreamReader类用于从文本文件中读取字符,是以文本为单位进行读取操作的。它可以读取文件中的字符串、字符和行等数据。当读取的字符集不是Unicode时,可以使用编码来转换字符集。

下表列出了 StreamReader 类中一些常用的方法

序号 方法 描述
1 public override void Close() 关闭 StreamReader 对象和基础流,并释放任何与读者相关的系统资源。
2 public override int Peek() 返回下一个可用的字符,但不使用它。
3 public override int Read() 从输入流中读取下一个字符,并把字符位置往前移一个字符。

示例代码:

using System;
using System.IO;

namespace FileIOApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // 指定读取的文件路径
            string filePath = "example.txt";
            
            // 创建一个 StreamReader 对象,以 UTF-8 编码方式打开指定文件
            StreamReader reader = new StreamReader(filePath);

            // 循环读取文件中的每一行直到文件末尾
            while (!reader.EndOfStream)
            {
                // 读取文件中的一行,并将其存储到 line 变量中
                string line = reader.ReadLine();
                
                // 在控制台中输出当前行
                Console.WriteLine(line);
            }

            // 关闭 StreamReader 对象
            reader.Close();
            
            // 等待用户按下任意键结束程序
            Console.ReadKey();
        }
    }
}
  • StreamWriter类用于向文本文件中写入字符,是以文本为单位进行写入操作的。它可以写入字符串、字符和行等数据。当写入的字符集不是Unicode时,可以使用编码来转换字符集。

下表列出了 StreamWriter 类中一些常用的方法

序号 方法 描述
1 public override void Close() 关闭当前的 StreamWriter 对象和基础流。
2 public override void Flush() 清理当前编写器的所有缓冲区,使得所有缓冲数据写入基础流。
3 public virtual void Write(bool value) 把一个布尔值的文本表示形式写入到文本字符串或流。(继承自 TextWriter。)
4 public override void Write( char value ) 把一个字符写入到流。
5 public virtual void Write( decimal value ) 把一个十进制值的文本表示形式写入到文本字符串或流。
6 public virtual void Write( double value ) 把一个 8 字节浮点值的文本表示形式写入到文本字符串或流。
7 public virtual void Write( int value ) 把一个 4 字节有符号整数的文本表示形式写入到文本字符串或流。
8 public override void Write( string value ) 把一个字符串写入到流。
9 public virtual void WriteLine() 把行结束符写入到文本字符串或流。

示例代码:

using System;
using System.IO;

namespace FileIOApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "example.txt";
            // 创建一个 StreamWriter 对象并传入文件路径,如果文件不存在则创建,如果存在则覆盖
            StreamWriter writer = new StreamWriter(filePath);

            // 向文件中写入两行文本
            writer.WriteLine("Hello World!");
            writer.WriteLine("Welcome to C# programming!");

            // 关闭 StreamWriter 对象
            writer.Close();
            Console.ReadKey();
        }
    }
}

在使用StreamReaderStreamWriter类时,需要注意关闭流,以释放相关资源,避免内存泄漏。可以使用Close方法或使用using语句块来自动关闭流。


3、BinaryReader 和 BinaryWriter 类

在C#中,BinaryReaderBinaryWriter 类是是用于读取和写入二进制文件的类。

  • BinaryReader 类用于从文件读取二进制数据。一个 BinaryReader 对象通过向它的构造函数传递 FileStream 对象而被创建。下表列出了 BinaryReader 类中一些常用的方法:
序号 方法 描述
1 public override void Close() 关闭 BinaryReader 对象和基础流。
2 public virtual int Read() 从基础流中读取字符,并把流的当前位置往前移。
3 public virtual bool ReadBoolean() 从当前流中读取一个布尔值,并把流的当前位置往前移一个字节。
4 public virtual byte ReadByte() 从当前流中读取下一个字节,并把流的当前位置往前移一个字节。
5 public virtual byte[] ReadBytes(int count) 从当前流中读取指定数目的字节到一个字节数组中,并把流的当前位置往前移指定数目的字节。
6 public virtual char ReadChar() 从当前流中读取下一个字节,并把流的当前位置按照所使用的编码和从流中读取的指定的字符往前移。
7 public virtual char[] ReadChars(int count) 从当前流中读取指定数目的字节,在一个字符数组中返回数组,并把流的当前位置按照所使用的编码和从流中读取的指定的字符往前移。
8 public virtual double ReadDouble() 从当前流中读取一个 8 字节浮点值,并把流的当前位置往前移八个字节。
9 public virtual int ReadInt32() 从当前流中读取一个 4 字节有符号整数,并把流的当前位置往前移四个字节。
10 public virtual string ReadString() 从当前流中读取一个字符串。字符串以长度作为前缀,同时编码为一个七位的整数。
  • BinaryWriter 类用于向文件写入二进制数据。一个 BinaryWriter 对象通过向它的构造函数传递 FileStream 对象而被创建。下表列出了 BinaryWriter 类中一些常用的方法:
序号 方法 描述
1 public override void Close() 关闭 BinaryWriter 对象和基础流。
2 public virtual void Flush() 清理当前编写器的所有缓冲区,使得所有缓冲数据写入基础设备。
3 public virtual long Seek( int offset, SeekOrigin origin ) 设置当前流内的位置。
4 public virtual void Write( bool value ) 把一个单字节的布尔值写入到当前流中,0 表示 false,1 表示 true。
5 public virtual void Write( byte value ) 把一个无符号字节写入到当前流中,并把流的位置往前移一个字节。
6 public virtual void Write( byte[] buffer ) 把一个字节数组写入到基础流中。
7 public virtual void Write( char ch ) 把一个 Unicode 字符写入到当前流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
8 public virtual void Write( char[] chars ) 把一个字符数组写入到当前流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
9 public virtual void Write( double value ) 把一个 8 字节浮点值写入到当前流中,并把流位置往前移八个字节。
10 public virtual void Write( int value ) 把一个 4 字节有符号整数写入到当前流中,并把流位置往前移四个字节。
11 public virtual void Write( string value ) 把一个以长度为前缀的字符串写入到 BinaryWriter 的当前编码的流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。

其中序号4-11的方法属于之前提到的函数重载,通过不同的参数类型实现。

下面的实例演示了读取和写入二进制数据:

using System;
using System.IO;

namespace BinaryFileApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            BinaryWriter bw; // 声明 BinaryWriter 对象
            BinaryReader br; // 声明 BinaryReader 对象
            int i = 25; // 定义一个 int 类型的变量 i
            double d = 3.14157; // 定义一个 double 类型的变量 d
            bool b = true; // 定义一个 bool 类型的变量 b
            string s = "I am happy"; // 定义一个 string 类型的变量 s

            // 创建文件
            try
            {
                bw = new BinaryWriter(new FileStream("mydata", FileMode.Create)); // 创建名为 mydata 的二进制文件
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message + "\n Cannot create file."); // 文件创建失败时输出错误信息
                return;
            }

            // 写入文件
            try
            {
                bw.Write(i); // 将变量 i 写入文件
                bw.Write(d); // 将变量 d 写入文件
                bw.Write(b); // 将变量 b 写入文件
                bw.Write(s); // 将变量 s 写入文件
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message + "\n Cannot write to file.");  // 写入文件失败时输出错误信息
                return;
            }

            bw.Close();  // 关闭 BinaryWriter 对象

            // 读取文件
            try
            {
                br = new BinaryReader(new FileStream("mydata", FileMode.Open)); // 打开名为 mydata 的二进制文件
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message + "\n Cannot open file."); 	// 文件打开失败时输出错误信息
                return;
            }

            try
            {
                i = br.ReadInt32(); 		// 读取 int 类型的数据并存储到变量 i 中
                Console.WriteLine("Integer data: {0}", i); 	// 输出变量 i 的值
                d = br.ReadDouble(); 		// 读取 double 类型的数据并存储到变量 d 中
                Console.WriteLine("Double data: {0}", d); 	// 输出变量 d 的值
                b = br.ReadBoolean(); 		// 读取 bool 类型的数据并存储到变量 b 中
                Console.WriteLine("Boolean data: {0}", b);	// 输出变量 b 的值
                s = br.ReadString(); 		// 读取 string 类型的数据并存储到变量 s 中
                Console.WriteLine("String data: {0}", s); 	// 输出变量 s 的值
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message + "\n Cannot read from file."); // 从文件读取数据失败时输出错误信息
                return;
            }

            br.Close(); // 关闭 BinaryReader 对象

            Console.ReadKey(); // 等待用户按下任意键继续执行程序
        }
    }
}

当上面的代码被编译和执行时,它会产生下列结果:

Integer data: 25
Double data: 3.14157
Boolean data: True
String data: I am happy


4、DirectoryInfo 类

DirectoryInfo 类派生自 FileSystemInfo 类。它提供了各种用于创建、移动、浏览目录和子目录的方法。该类不能被继承。

DirectoryInfo的实例化语法如下:

DirectoryInfo dir = new DirectoryInfo("path");
  • 其中 path 是一个字符串,指定了目录的路径,可以使用绝对路径或相对路径

下表列出了 DirectoryInfo 类中一些常用的属性

序号 属性 描述
1 Attributes 获取当前文件或目录的属性。
2 CreationTime 获取当前文件或目录的创建时间。
3 Exists 获取一个表示目录是否存在的布尔值。
4 Extension 获取表示文件存在的字符串。
5 FullName 获取目录或文件的完整路径。
6 LastAccessTime 获取当前文件或目录最后被访问的时间。
7 Name 获取该 DirectoryInfo 实例的名称。

下表列出了 DirectoryInfo 类中一些常用的方法

序号 方法 描述
1 public void Create() 创建一个目录。
2 public DirectoryInfo CreateSubdirectory(string path) 在指定的路径上创建子目录。指定的路径可以是相对于 DirectoryInfo 类的实例的路径。
3 public override void Delete() 如果为空的,则删除该 DirectoryInfo。
4 public DirectoryInfo[] GetDirectories() 返回当前目录的子目录。
5 public FileInfo[] GetFiles() 从当前目录返回文件列表。

以下是使用 DirectoryInfo 类的示例代码,包括实例化 DirectoryInfo 对象、获取目录信息、创建目录和删除目录:

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        // 实例化 DirectoryInfo 对象
        DirectoryInfo directory = new DirectoryInfo(@"C:\temp");

        // 获取目录(属性)信息
        Console.WriteLine($"Directory Name: {directory.Name}");
        Console.WriteLine($"Full Directory Name: {directory.FullName}");
        Console.WriteLine($"Parent Directory: {directory.Parent}");
        Console.WriteLine($"Creation Time: {directory.CreationTime}");
        Console.WriteLine($"Last Access Time: {directory.LastAccessTime}");
        Console.WriteLine($"Last Write Time: {directory.LastWriteTime}");

        // 创建目录
        if (!directory.Exists)
        {
            directory.Create();
            Console.WriteLine("Directory created successfully.");
        }
        else
        {
            Console.WriteLine("Directory already exists.");
        }

        // 删除目录
        directory.Delete();
        Console.WriteLine("Directory deleted successfully.");

        Console.ReadKey();
    }
}

5、FileInfo 类

FileInfo 类派生自 FileSystemInfo 类。它提供了用于创建、复制、删除、移动、打开文件的属性和方法,且有助于 FileStream 对象(用于文件读写)的创建。该类不能被继承。

  • 实例化 FileInfo 类时,同样需要指定文件路径作为构造函数的参数,例如:
FileInfo fileInfo = new FileInfo("path/to/file.txt");

下表列出了 FileInfo 类中一些常用的属性

序号 属性 描述
1 Attributes 获取当前文件的属性。
2 CreationTime 获取当前文件的创建时间。
3 Directory 获取文件所属目录的一个实例。
4 Exists 获取一个表示文件是否存在的布尔值。
5 Extension 获取表示文件存在的字符串。
6 FullName 获取文件的完整路径。
7 LastAccessTime 获取当前文件最后被访问的时间。
8 LastWriteTime 获取文件最后被写入的时间。
9 Length 获取当前文件的大小,以字节为单位。
10 Name 获取文件的名称。

下表列出了 FileInfo 类中一些常用的方法

序号 方法 描述
1 public StreamWriter AppendText() 创建一个 StreamWriter,追加文本到由 FileInfo 的实例表示的文件中。
2 public FileStream Create() 创建一个文件。
3 public override void Delete() 永久删除一个文件。
4 public void MoveTo( string destFileName ) 移动一个指定的文件到一个新的位置,提供选项来指定新的文件名。
5 public FileStream Open( FileMode mode ) 以指定的模式打开一个文件。
6 public FileStream Open( FileMode mode, FileAccess access ) 以指定的模式,使用 read、write 或 read/write 访问,来打开一个文件。
7 public FileStream Open( FileMode mode, FileAccess access, FileShare share ) 以指定的模式,使用 read、write 或 read/write 访问,以及指定的分享选项,来打开一个文件。
8 public FileStream OpenRead() 创建一个只读的 FileStream。
9 public FileStream OpenWrite() 创建一个只写的 FileStream。

以下是使用 FileInfo 类的示例代码:文章来源地址https://www.toymoban.com/news/detail-842526.html

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        // 创建 FileInfo 实例
        FileInfo file = new FileInfo("test.txt");

        // 检查文件是否存在
        if (file.Exists)
        {
            Console.WriteLine("文件已存在。");

            // 获取文件的创建时间和修改时间
            Console.WriteLine("文件创建时间:" + file.CreationTime);
            Console.WriteLine("文件修改时间:" + file.LastWriteTime);

            // 获取文件大小(以字节为单位)
            Console.WriteLine("文件大小:" + file.Length + " 字节");

            // 获取文件名和文件路径
            Console.WriteLine("文件名:" + file.Name);
            Console.WriteLine("文件路径:" + file.FullName);

            // 重命名文件
            FileInfo newFile = new FileInfo("newTest.txt");
            file.MoveTo(newFile.FullName);
            Console.WriteLine("文件已重命名为:" + newFile.Name);

            // 删除文件
            newFile.Delete();
            Console.WriteLine("文件已删除。");
        }
        else
        {
            // 创建文件
            using (StreamWriter sw = file.CreateText())
            {
                sw.WriteLine("这是一个测试文件。");
            }

            Console.WriteLine("文件已创建。");
        }

        Console.ReadKey();
    }
}

到了这里,关于unity的C#学习——预处理指令、异常处理和文件的输入输出的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#_预处理指令

    1.         预处理器指令指导编译器在实际编译开始之前对信息进行预处理。         所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。         C# 编译器没有一个单

    2024年02月09日
    浏览(36)
  • 什么是预处理器指令,常用的预处理器指令有哪些?什么是运算符,C 语言中的运算符有哪些?

    预处理器指令是一种用于在源代码编译之前进行预处理的特殊指令。它们通过在程序编译之前对源代码进行处理,可以在编译阶段之前进行一些文本替换、条件编译等操作,从而对源代码进行一些宏定义、条件编译等操作。 常用的预处理器指令有以下几种: #define:用于定义

    2024年02月15日
    浏览(52)
  • 015+limou+C语言深入知识——(7)编译环境和运行环境以及预处理指令

    在这个环境中,源代码被转化为可执行的机器指令(二进制指令) 单文件简易版本 多文件简易版本 编译链接详细版本 VS2022集成IDE(windows下)的编译器叫cl.exe,链接器叫link.exe gcc编译器(windows下)的几个有关编译环境的命令 (1)符号表会把全局变量和具有外部链接的函数

    2023年04月11日
    浏览(38)
  • 在C++中控制调试信息的输出通常通过预处理指令(如 #define)和条件编译指令(如 #ifdef、#ifndef、#endif)来实现。

    在C++中,控制调试信息的输出通常通过预处理指令(如 #define )和条件编译指令(如 #ifdef 、 #ifndef 、 #endif )来实现。这种方法提供了一种灵活的方式来包含或排除调试代码,而无需对代码本身进行大量修改。以下是实现这一功能的一种常见方法: 定义一个宏用于控制调试

    2024年02月02日
    浏览(39)
  • Apifox使用外部文件完成接口预处理

    pm.executeAsync(filePath, args, options) filePath string 外部程序路径 args string[] 参数。调用 jar 包中的指定方法时,会使用 JSON.stringify 进行转换。除此之外非 string 类型会进行隐式类型转换自动转换为 string 类型。 options Object command string 外部程序的执行命令,“命令前缀”中的前面部分

    2024年01月23日
    浏览(53)
  • 机器学习(8)---数据预处理

     1. 在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布的需求,这种需求统称为将数据“无量纲化”。 譬如梯度和矩阵为核心的算法中,譬如逻辑回归,支持向量机,神经网络,无量纲化可以加快求解速度. 而在

    2024年02月09日
    浏览(39)
  • 大数据采集技术与预处理学习一:大数据概念、数据预处理、网络数据采集

    目录 大数据概念: 1.数据采集过程中会采集哪些类型的数据? 2.非结构化数据采集的特点是什么? 3.请阐述传统的数据采集与大数据采集的区别? ​​​​​​​ ​​​​​​​4.大数据采集的数据源有哪些?针对不同的数据源,我们可以采用哪些不同的方法和工具? 数据

    2024年01月25日
    浏览(52)
  • 动手学深度学习——数据预处理

    为了能用深度学习来解决现实世界的问题,我们经常从预处理原始数据开始,而不是从那些准备好的张量格式数据开始。 在Python中常用的数据分析工具中,我们通常使用 pandas 软件包。像庞大的Python生态系统中的许多其他扩展包一样, pandas 可以与张量兼容。 举一个例子,我

    2024年02月16日
    浏览(56)
  • 机器学习实战4-数据预处理

    导库 归一化 另一种写法 将归一化的结果逆转 用numpy实现归一化 逆转 导库 实例化 查看属性 查看结果 逆标准化 关于如何选择这两种无量纲化的方式要具体问题具体分析,但是我们一般在机器学习算法中选择标准化,这就好比我们能让他符合标准正态分布为什么不呢?而且

    2024年02月13日
    浏览(43)
  • 机器学习:特征工程之特征预处理

    目录 特征预处理 1、简述 2、内容 3、归一化 3.1、鲁棒性 3.2、存在的问题 4、标准化 ⭐所属专栏:人工智能 文中提到的代码如有需要可以私信我发给你😊 什么是特征预处理:scikit-learn的解释: provides several common utility functions and transformer classes to change raw feature vectors into a r

    2024年02月12日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包