C#文件操作学习

本文对比了Java与C#在文件操作和流处理方面的差异,C#通过明确的File和Directory类,简化了文件和目录操作,并介绍了工厂方法和普通类的使用。重点讲解了流操作的设计模式,展示了C#如何利用FileStream的多样性创建方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**前言:**文件操作及相关的流操作是每一种编程语言的必备部分
就我学过的Java来对比最近正在学习的C#,对比发现,确实
C#文件操作相关相比Java较为简单,比较好使用

第一,C#将File和Dirtory明确的分开,避免混淆了文件夹和具体文件。

第二,C#的文件操作分一套工厂类和一套普通的使用类。

整个分割线吧------------------------------------------------------------------------------------------------------------------

工厂类

      这点可以从源码分析看出,File和Dirtory都是一组静态类,
      其中的所有方法都是静态方法,也就是说,它不可以生成实体对象。
public static class File
    {
        public static void AppendAllLines(string path, IEnumerable<string> contents);
        public static void AppendAllLines(string path, IEnumerable<string> contents, Encoding encoding);
        public static Task AppendAllLinesAsync(string path, IEnumerable<string> contents, CancellationToken cancellationToken = default);
        public static void AppendAllText(string path, string contents);
        public static void AppendAllText(string path, string contents, Encoding encoding);
        public static StreamWriter AppendText(string path);
        public static void Copy(string sourceFileName, string destFileName);
        public static void Copy(string sourceFileName, string destFileName, bool overwrite);
        public static FileStream Create(string path);
        public static FileStream Create(string path, int bufferSize);
        public static FileStream Create(string path, int bufferSize, FileOptions options);
        public static StreamWriter CreateText(string path);
        public static void Decrypt(string path);
        public static void Delete(string path);
        public static void Encrypt(string path);
        public static bool Exists(string path);
        public static DateTime GetCreationTime(string path);
        public static DateTime GetCreationTimeUtc(string path);
        public static DateTime GetLastAccessTime(string path);
        public static DateTime GetLastAccessTimeUtc(string path);
        public static DateTime GetLastWriteTime(string path);
        public static DateTime GetLastWriteTimeUtc(string path);
        public static void Move(string sourceFileName, string destFileName);
        public static FileStream Open(string path, FileMode mode);
        public static FileStream Open(string path, FileMode mode, FileAccess access);
        public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share);
        public static FileStream OpenRead(string path);
        public static StreamReader OpenText(string path);
        public static FileStream OpenWrite(string path);
        public static byte[] ReadAllBytes(string path);
        public static Task<byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default);
        public static string[] ReadAllLines(string path);
        public static string[] ReadAllLines(string path, Encoding encoding);
        public static Task<string[]> ReadAllLinesAsync(string path, CancellationToken cancellationToken = default);
        public static string ReadAllText(string path);
        public static string ReadAllText(string path, Encoding encoding);
        public static Task<string> ReadAllTextAsync(string path, CancellationToken cancellationToken = default);
        public static Task<string> ReadAllTextAsync(string path, Encoding encoding, CancellationToken cancellationToken = default);
        public static IEnumerable<string> ReadLines(string path);
        public static IEnumerable<string> ReadLines(string path, Encoding encoding);
        public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName);
        public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors);
        public static void SetAttributes(string path, FileAttributes fileAttributes);
        public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc);
        public static void SetLastAccessTime(string path, DateTime lastAccessTime);
        public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);
        public static void SetLastWriteTime(string path, DateTime lastWriteTime);
        public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);
        public static void WriteAllBytes(string path, byte[] bytes);
        public static Task WriteAllBytesAsync(string path, byte[] bytes, CancellationToken cancellationToken = default);
        public static void WriteAllLines(string path, string[] contents);
        public static void WriteAllLines(string path, IEnumerable<string> contents);
        public static void WriteAllLines(string path, string[] contents, Encoding encoding);
        public static void WriteAllLines(string path, IEnumerable<string> contents, Encoding encoding);
        public static Task WriteAllLinesAsync(string path, IEnumerable<string> contents, CancellationToken cancellationToken = default);
        public static void WriteAllText(string path, string contents);
        public static void WriteAllText(string path, string contents, Encoding encoding);
        public static Task WriteAllTextAsync(string path, string contents, CancellationToken cancellationToken = default);
        public static Task WriteAllTextAsync(string path, string contents, Encoding encoding, CancellationToken cancellationToken = default);
    }
}
public static class Directory
    {
        public static DirectoryInfo CreateDirectory(string path);
        public static void Delete(string path);
        public static void Delete(string path, bool recursive);
        public static IEnumerable<string> EnumerateDirectories(string path);
        public static IEnumerable<string> EnumerateDirectories(string path, string searchPattern);
        public static IEnumerable<string> EnumerateDirectories(string path, string searchPattern, EnumerationOptions enumerationOptions);
        public static IEnumerable<string> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption);
        public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption);
        public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, EnumerationOptions enumerationOptions);
        public static IEnumerable<string> EnumerateFiles(string path);
        public static IEnumerable<string> EnumerateFileSystemEntries(string path);
        public static IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern);
        public static IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern, EnumerationOptions enumerationOptions);
        public static IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption);
        public static bool Exists(string path);
        public static DateTime GetCreationTime(string path);
        public static DateTime GetCreationTimeUtc(string path);
        public static string[] GetDirectories(string path, string searchPattern, EnumerationOptions enumerationOptions);
        public static string[] GetDirectories(string path, string searchPattern, SearchOption searchOption);
        public static string[] GetDirectories(string path);
        public static string[] GetDirectories(string path, string searchPattern);
        public static string GetDirectoryRoot(string path);
        public static string[] GetFiles(string path);
        public static string[] GetFiles(string path, string searchPattern);
        public static string[] GetFiles(string path, string searchPattern, EnumerationOptions enumerationOptions);
        public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption);
        public static string[] GetFileSystemEntries(string path);
        public static string[] GetFileSystemEntries(string path, string searchPattern);
        public static string[] GetFileSystemEntries(string path, string searchPattern, EnumerationOptions enumerationOptions);
        public static string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption);
        public static DateTime GetLastAccessTime(string path);
        public static DateTime GetLastAccessTimeUtc(string path);
        public static DateTime GetLastWriteTime(string path);
        public static DateTime GetLastWriteTimeUtc(string path);
        public static string[] GetLogicalDrives();
        public static void Move(string sourceDirName, string destDirName);
        public static void SetCreationTime(string path, DateTime creationTime);
        public static void SetCurrentDirectory(string path);
        public static void SetLastAccessTime(string path, DateTime lastAccessTime);
        public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);
        public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);
    }
}

可以看出,非常简洁,全部都是静态方法,也可以说是工厂方法,可以直接调用,非常的简单
下面来简单的使用一下

static void Main(string[] args)
   {
       Console.WriteLine("Write Something Into File:");

       // File.Create("F:\\fuckyou.txt");   // 創建文件
       
       String Context = Console.ReadLine();
      
       File.WriteAllLines("F:\\fuckyou.txt",new String[] { Context});   //將一個字符串數組寫入文件

       Console.WriteLine("該文件創建時間:"+ File.GetCreationTime("F:\\fuckyou.txt")+"\n"
           +"文件寫入時間"+ File.GetLastWriteTime("F:\\fuckyou.txt")+"\n"+File.GetLastAccessTime("F:\\fuckyou.txt"));

       Console.ReadKey();
   }

运行:

Write Something Into File:
2021 ---- HOLY SHIT ----DUNGEON MASTER
該文件創建時間:2021/11/10 10:31:50
文件寫入時間2021/11/10 10:38:02
2021/11/10 10:31:50

这样就创建并写入了文件了,打开得到一下内容

2021 ---- HOLY SHIT ----DUNGEON MASTER

再测试一下文件夹

static void Main(string[] args)
 {
     Directory.CreateDirectory("F:\\新日暮里");

     foreach (String dir in Directory.EnumerateDirectories("C:\\Program Files"))
     {
         Console.WriteLine(dir);
     }

     Directory.SetCreationTime("F:\\新日暮里", new DateTime(2077,12,31,11,22,33));

 }

将所有的文件夹打印在控制台里

C:\Program Files\XXX
C:\Program Files\XXX
C:\Program Files\XXX
C:\Program Files\XXX
C:\Program Files\XXX
C:\Program Files\XXX
C:\Program Files\XXX
.........

并新建了文件夹

普通类

工厂类虽然简单,但是都必须要提供准确的文件路径作为参数,有的时候不是很方便,
这个时候就必须使用普通的文件和文件夹类了
在C#中,文件和文件夹类是FileInfo和DirectoryInfo,它们用于创建文件及文件夹对象,并提供了一套和工厂类相似的API.
这里以将对象写入文件举一个例子:

static void Main(string[] args)
 {
     FileInfo file = new FileInfo("F:\\fuckyou.txt");

     FileStream fs = file.OpenWrite();

     Person p1 =  new Person("3605XXXXXX", "Stack", "skull");

     byte[] buffer = ConvertToBuffer(p1);   //将对象转化为字节数组,然后写入文件

     fs.Write(buffer);

     fs.Close();   //最后关闭流

 }

     public static byte[] ConvertToBuffer(Object obj)
     {
         byte[] buffer;
         MemoryStream ms = new MemoryStream();       //使用BinaryFormatter转化成二进制byte
         IFormatter iFormatter = new BinaryFormatter();
         iFormatter.Serialize(ms, obj);
         buffer = ms.GetBuffer();
         ms.Dispose();
         return buffer;
     }

     [Serializable] //必要
     private class Person              //如果要使用BinaryFormatter将对象转化为二进制
     {                                 //对象的类必须实现序列化
         public String pid { get; set; }
         public String pname { get; set; }
         public String paddress { get; set; }
         public Person(String id,String name,String address)
         {
             pid = id;pname = name;paddress = address;
         }

         public Person()
         {
         }
     }

打开目标文本文件查看

              DFileAndIODemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   FileAndIODemo.Program+Person
    <pid>k__BackingField<pname>k__BackingField<paddress>k__BackingField      
3605XXXXXX   Stack   skull         

感觉格式比较奇怪,但确实是吧所有的信息都序列化写入文件了…
再试一试DirectoryInfo,

DirectoryInfo directory = new DirectoryInfo("C:\\Program Files");

foreach(DirectoryInfo item in directory.GetDirectories())
{
   Console.WriteLine(item.Name);
}

Console.ReadKey();

结果也同上:

7-Zip
XXXXX
XXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX
XXXXXXX
XXX
XXX
...........

文件流的操作(文件的读写)

文件的读写必须通过文件流操作,它归属于流操作也就是IO,
在我比较熟悉的Java中,
流操作是一种典型的装饰模式的设计
(在我的设计模式文章中有专门研究)
基础无疑是InputStream和OutputStream,
在它之上的装饰类有很多,各种Writer,Reader什么的(字符流),
还有DataIn&OutputStream,BUfferedIN&OutputStream,ObjectIn&OutputStream
ZipIn&OutStream…
包括FileIn&OutputStream都是它的的包装类.

分割线--------------------------------------------------------------------------------------
在C#中好像也使用了相同的设计模式,
但不分输入和输出(感觉有点别扭C++还用在用Cin>>和Cout<<)
FileStream的创建方法有很多:

public FileStream(SafeFileHandle handle, FileAccess access);
       
        public FileStream(IntPtr handle, FileAccess access);
       
        public FileStream(string path, FileMode mode);
       
        public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize);
       
        public FileStream(string path, FileMode mode, FileAccess access);
        
        public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync);
        
        public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize);
       
        public FileStream(string path, FileMode mode, FileAccess access, FileShare share);
       
        public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize);
       
        public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync);
       
        public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync);
       
        public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options);

其中涉及一些枚举类需要仔细看一看
FileMode

public enum FileMode
    {
         //创建新文件,已存在则会报错
        CreateNew = 1,
        //创建新文件
        Create = 2,
        //打开
        Open = 3,
       //打开或创建
        OpenOrCreate = 4,
       //打开现有文件,清除其内容。流指向文件的开头,保留文件的初始创建日期
        Truncate = 5,
        //追加
        Append = 6
    }

FileAccess

public enum FileAccess
    {
        //只用于读取
        Read = 1,
       //只用于写入
        Write = 2,
        //可读写
        ReadWrite = 3
    }

FileShare文件共享锁(不确定)

public enum FileShare
    {
       . //无锁
        None = 0,
         //读锁
        Read = 1,
         //写锁
        Write = 2,
         //读写锁
        ReadWrite = 3,
         //删除
        Delete = 4,
        //
        // 摘要:
        //     Makes the file handle inheritable by child processes. This is not directly supported
        //     by Win32.
        Inheritable = 16
    }

如果不是多线程环境下则不要指定FileShare参数

现在测试一下流操作

FileStream fs = new FileStream("F:\\fuckyou.txt", FileMode.OpenOrCreate);

fs.Write(Encoding.Default.GetBytes("||11ll||1l|||------------|||||||"));

fs.Close();
||11ll||1l|||------------|||||||Demo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   FileAndIODemo.Program+Person   <pid>k__BackingField<pname>k__BackingField<paddress>k__BackingField      
3605XXXXXX   Stack   skull         

或者可以从File或FileInfo中后期文件流,


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jamenu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值