C# 小结-文件

转自:https://blog.csdn.net/qq_39710961/article/details/76890142

大多数应用程序都需要实现与设备之间的数据传输,例如键盘可以输入数据,显示器可以显示程序的运行结果等,在 C#中将这种通过不同输入/输出设备(键盘、内存、显示器、网络等)之间的数据传输抽象表述为“流”,程序允许通过流的方式与输入/输出设备进行数据传输。C#中的“流”都位于System.IO命名空间中,称为IO(输入/输出)流。

在计算机中,无论是文本、图片、音频还是视频,所有的文件都是以二进制(字节)形式存储的。为此,C#专门针对文件的输入/输出操作提供了一系列的流,统称为文件流。文件流是程序中最常用的流,根据数据的传输方向可将其分为输入流和输出流。为了方便理解,可以把输入流和输出流比作两根“水管”,如图所示:

C# 小结-文件_第1张图片

流中的输入/输出都是相对于程序而言的

在 C#中对文件操作的类都位于 System.IO 命名空间中,因此在使用这些类时需要引入System.IO命名空间。该命名空间中包含了很多类,为了方便初学者更好地学习,接下来通过一个图例来介绍System.IO命名空间中的常用类,如图所示。

C# 小结-文件_第2张图片

这些类大致可分为操作目录的类、操作文件的类、操作文件路径的类等。其中,Directory类和DirectoryInfo类属于操作目录的类,FileStream类、File类和FileInfo 类属于操作文件的类,StreamReader 类、StreamWriter 类属于操作文本文件的类,Path类属于操作文件路径的类。

这就是文件引入的原因,和用处!

相对路径是指当前文件相对于其他文件(或文件夹)之间的路径关系。例如在路径D:\itcast\a\b\下有程序文件“b.cs”和文本文件“a.txt”这两个文件,那么相对于“b.cs”文件来说,“a.txt”文件就是在同一文件目录下,所以在“b.cs”文件中调用“a.txt”文件直接写文件名便可。相对路径使用符号“/”表示,具体使用方式如下。
● 在斜杠前面加一个点(./)表示上一级目录;
● 在斜杠前面加两个点(../)表示当前文件的根目录。

绝对路径是指文件在磁盘上的的完整路径,例如 b.cs 程序调用 a.txt 时,填写“D:\itcast\a\b\a.txt”,在程序中使用绝对路径时需要注意该路径的位置,当该位置发生改变时可能会导致异常。

C# 小结-文件_第3张图片


流可以对文件的内容进行读写操作,而在应用程序中还可能会对文件自身进行一些操作,例如创建、删除或者重命名某个文件,判断磁盘上某个文件是否存在等。针对这些操作,C#中提供了File类和FileInfo类这两个类

File 类是一个静态类,它提供了许多静态方法,用于处理文件,使用这些方法可以对文件进行创建、移动、查询和删除等操作,接下来介绍 File 类的一些常用的静态方法,如表所示。
C# 小结-文件_第4张图片

     }
        //文件创建
        static void Test01(string path)
        {
            //文件的创建
            if (File.Exists(path))
            {
                Console.WriteLine("文件已经存在");
            }
            else
            {
                //如果不存在则创建文件
                File.Create(path);
            }
        }
        //文件的移动  和文件的重命名
        static void Test02(string sourcePath,string destPath)
        {
            File.Move(sourcePath, destPath);
        }
  static void Test04(string path)
        {
            //从文件读取数据的流
            FileStream fs = File.Open(path, FileMode.OpenOrCreate, FileAccess.Read);
            byte[] byteArr = new byte[4096];
            int len = 0;
            string destPath = @"D:\FileTest\1707A\Newaa.txt";
            //写入文件的流
            FileStream fsWrite = File.Open(destPath, FileMode.OpenOrCreate, FileAccess.Write);
            //len表示 在调用Read方法的时候  从文件中实际读取的字节数
            while ((len = fs.Read(byteArr, 0, byteArr.Length)) != 0)
            {
                fsWrite.Write(byteArr, 0, len);
            }
              static void Test01(string sourcePath,string destPath)
        {
            FileStream fsRead = null;
            FileStream fsWrite = null;
            try
            {
                fsRead = new FileStream(sourcePath, FileMode.OpenOrCreate, FileAccess.Read);
                fsWrite = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write);
                int temp = -1;
                while ((temp = fsRead.ReadByte()) != -1)
                {
                    fsWrite.WriteByte((byte)temp);
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);

            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                fsRead.Close();
                fsWrite.Close();
            }
        }
ileInfo类与File类有些类似,它们都可以对磁盘上的文件进行操作。不同的是FileInfo类是实例类,所有的方法都只能在实例化对象后才能调用。创建 FileInfo 类对象时必须传递一个文件路径作为参数,具体语法格式如下。
FileInfo aFile = new FileInfo(@"C:\Data.txt");
上述代码表示使用 FileInfo 类创建一个对象,将文件路径作为参数,而路径中“@”符号表示不解析转义字符,如果没有“@”前缀就需要用“\\”替代“\”。通过前面的学习可知,“\”是一个转义字符,在程序中要表示一个“\”就需要使用“\\”。例如下面这句代码。
FileInfo aFile = new FileInfo("C:\\Data.txt");
FileInfo类除了有许多与File类相似的方法外,同时也有它特有的属性

C# 小结-文件_第5张图片

   static void Main(string[] args)
        {
            string path = @"D:\FileTest\1707A\aa.txt";
            string destPath = @"D:\FileTest\1707A\bb.txt";
            Test01(path,destPath);
        }

 static void Test01(string path,string destPath)
        {
            FileInfo fi = new FileInfo(path);
            //获取当前文件所在的目录
            Console.WriteLine(fi.Directory);
            //获取当前文件所在的目录
            Console.WriteLine(fi.DirectoryName);
            //判断文件是否是只读的
            Console.WriteLine(fi.IsReadOnly);
            //获取文件的大小 单位是字节
            Console.WriteLine(fi.Length);
            //类似拷贝  复制操作  如果目标目录下面有相同的文件 则会抛出异常
            //fi.CopyTo(destPath);
            //类似剪切操作
            //fi.MoveTo(@"D:\FileTest\1707A\YY\bb.txt");
            StreamWriter sw = fi.AppendText();
            sw.Write("abcdefg");
            //强制刷出缓冲区中的数据
            sw.Flush();
            //关闭流
            sw.Close();
        }

在程序开发中,不仅需要对文件进行操作,而且还需要对文件目录进行操作。例如创建目录,删除目录等,为此C#提供了Directory类和DirectoryInfo类。

Directory类是静态类,提供了许多静态方法用于对目录进行操作,例如创建、删除、查询和移动目录等。

C# 小结-文件_第6张图片

 static void Main(string[] args)
        {
            string path = @"D:\FileTest\1707A\ZZ";
            Test01(path);
        }
        static void Test01(string path)
        {
            //Directory.CreateDirectory(path);
            //获取当前文件夹所在文件目录的信息
            DirectoryInfo di = Directory.GetParent(path);
            //
            Console.WriteLine(di.FullName);
        }

DirectoryInfo类的功能与Directory类相似,不同的是DirectoryInfo是一个实例类,该类不仅拥有与Directory类功能相似的方法,而且还具有一些特有的属性。下面图中是常用的属性C# 小结-文件_第7张图片

文件的读取和写入

FileStream类不仅可以以字节的方式读取,还可以对文件的位置进行读取,在FileStream类的内部有一个文件指针用于维护文件位置,该指针指向文件进行下一次读写操作的位置。大多数情况下,当打开文件时,指针均指向文件的开始位置,如果想修改指针的位置可以使用FileStream对象的Seek()方法,具体用法如下。
FileStream aFile=File.OpenRead("Data.txt");
aFile.Seek(8,SeekOrigin.Current);
Seek()方法的第一个参数表示文件指针移动距离(以字节为单位),第二个参数表示开始计算的起始位置,用SeekOrigin枚举类型的一个值表示,SeekOrigin枚举包含3个值:Begin、Current和End,其中Begin表示文件开始位置,Current表示文件当前位置,End表示文件结束位置。


FileStream 类向文件中写入数据的过程与读取数据的过程非常相似,不同的是,读取数据时使用的是Read()方法,而写入时使用的是Write()方法,

FileStream 类表示在磁盘或网络路径上指向文件的流,并提供了在文件中读写字节和字节数组的方法,通过这些方法,FileStream 对象可以读取诸如图像、声音、视频、文本文件等,也就是说FileStream类能够处理各种数据文件。
FileStream类有很多重载的构造方法,其中最常用的是带有三个参数的构造方法,具体如下。
FileStream(string path, FileMode mode, FileAccess access);
上述构造方法中,第一个参数path表示的是文件路径名,第二个参数mode表示如何打开或创建文件,第三个参数access用于确定 FileStream 对象访问文件的方式。除了这个构造方法外,FileStream类还有一些常用的方法

C# 小结-文件_第8张图片

   static void Main(string[] args)
        {
            string path1 = @"D:\FileTest\aa.txt";
            string path2 = @"D:\FileTest\cc.txt";
            Test01(path1,path2);
        }
        static void Test01(string sourcePath,string destPath)
        {
            FileStream fsRead = null;
            FileStream fsWrite = null;
            try
            {
                fsRead = new FileStream(sourcePath, FileMode.OpenOrCreate, FileAccess.Read);
                fsWrite = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write);
                int temp = -1;
                while ((temp = fsRead.ReadByte()) != -1)
                {
                    fsWrite.WriteByte((byte)temp);
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);

            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                fsRead.Close();
                fsWrite.Close();
            }          
        }

前面用到的 FileStream 类只能通过字节或字节数组的方式对文件进行操作,当处理文本文件时还需要在字节与字符数据之间进行转换,这时程序会显得过于繁琐。为此,C#专门提供了StreamReader类和StreamWriter类用于处理文本文件。

StreamWriter类用于将字符和字符串写入文件,它实际上也是先转换成FileStream对象,然后向文件中写入数据的,所以在创建对象时可以通过FileStream对象来创建StreamWriter对象,同时也可以直接创建StreamWriter对象。
当FileStream对象存在时,可以通过该对象来创建StreamWriter对象,具体语法如下。
FileStream aFile = new FileStream("Data.txt",FileMode.CreateNew);
StreamWriter sw = new StreamWriter(aFile);
除了上述这种方式以外,还可以通过指定文件来创建StreamWriter对象,具体语法如下。
StreamWriter sw = new StreamWriter("Data.txt");
上述代码表示创建一个StreamWriter流对象,并向Data.txt文件中写入数据。如果Data.txt文件不存在则创建该文件。


StreamWriter类其实是对FileStream流进行封装,并实现了字节流对字符流的转换,StreamReader类也是如此,只是StreamReader类是以字符的形式读取文件的。StreamReader 类型的对象可以通过 FileStream 类型的对象来创建,同时也可以直接创建StreamWriter类型的对象。下面就针对这两种语法格式进行讲解。
当FileStream类型的对象存在时可以通过该对象来创建StreamWriter类型的对象,具体语法如下。
FileStream aFile = new FileStream("Data.txt",FileMode.Open);
StreamReader sr = new StreamReader(aFile);
StreamReader 类与 StreamWriter 类一样,可以通过具体文件路径的字符串来创建StreamReader类型的对象,具体语法如下。
StreamReader sr = new StreamReader("Data.txt");在前面的学习中都是将文件存储到硬盘,但有时希望将文件临时存储到缓冲区中,方便以后读取。为此C#中提供了BufferedStream类。BufferedStream类必须和其他流一起使用,并将这些流写入内存中,这样可以提高读取和写入速度。

 static void Main(string[] args)
        {
            string path1 = @"D:\FileTest\1707A\Newaa.txt";
            string path2 = @"D:\FileTest\1707A\Newbb.txt";
            Test02(path1,path2);
        }

        static void Test01(string path1,string path2)
        {
            FileStream fsReader = new FileStream(path1,FileMode.OpenOrCreate,FileAccess.Read);
            StreamReader sr = new StreamReader(fsReader,Encoding.Default);

            FileStream fsWriter = new FileStream(path2,FileMode.OpenOrCreate,FileAccess.Write);
            StreamWriter sw = new StreamWriter(fsWriter,Encoding.Unicode);
            int temp = -1;
            while((temp = sr.Read()) != -1)
            {
                sw.Write((char)temp);
            }
            //刷出缓存区的数据
            sw.Flush();
            //关闭流
            sw.Close();
            //关闭流
            fsWriter.Close();
        }

        static void Test02(string path1, string path2)
        {
            FileStream fsReader = new FileStream(path1,FileMode.OpenOrCreate,FileAccess.Read);
            StreamReader sr = new StreamReader(fsReader,Encoding.Default);

            FileStream fsWriter = new FileStream(path2,FileMode.OpenOrCreate,FileAccess.Write);
            StreamWriter sw = new StreamWriter(fsWriter,Encoding.Default);

            string str = string.Empty;
            while((str = sr.ReadLine()) != null)
            {
                sw.WriteLine(str);
                
            }
            sw.Flush();
            sw.Close();
        }

BufferedStream类提供了几个常用的操作方法,即Read()方法、Write()方法和Flush()方法,具体分析如下。
1.Read()方法
Read()方法用于读取缓冲区中的数据,具体语法格式如下。
public override int Read(byte[] array,int offset, int count);
Read()方法有三个参数,其中第一个参数array表示将字节复制到缓冲区,第二个参数offset表示索引位置,从此处开始读取字节,第三个参数 count 表示要读取的字节数。该方法的返回值是int类型,表示读取array字节数组中的总字节数,如果实际字节小于请求的字节数,就返回实际读取的字节数。
2.Write()方法
Write()方法用于将字节复制到缓冲流,并在缓冲流内的当前位置继续写入字节,具体语法格式如下。
public override int Write(byte[] array,int offset,int count);
该方法同样有三个参数,其作用与 Read()方法中参数的作用类似,只不过都是针对字节进行写入操作。
3.Flush()方法
Flush()方法用于清除当前流中的所有缓冲区,使得所有缓冲的数据都被写入存储设备中,具体语法格式如下。
public override void Flush()
Flush()方法比较简单,既没有参数也没用返回值。
        static void Main(string[] args)
        {
            string path = @"D:\FileTest\1707A\Newaa.txt";
            string path1 = @"D:\FileTest\1707A\Newcc.txt";
            FileStream fsRead = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Read);
            BufferedStream bsRead = new BufferedStream(fsRead);
            FileStream fsWrite = new FileStream(path1,FileMode.OpenOrCreate,FileAccess.Write);
            BufferedStream bsWrite = new BufferedStream(fsWrite);
            int len = 0;
            byte[] byteArr = new byte[4096];
            while ((len = bsRead.Read(byteArr,0,byteArr.Length))!=0)
            {
                bsWrite.Write(byteArr,0,len);
            }
            bsWrite.Flush();
            bsWrite.Close();

     }


你可能感兴趣的:(C#语言特性)