最全的C#文件操作

操作某一个文件/文件夹,需要一个文件的完整路径

一、使用File的静态方法进行文件操作

//使用file的静态方法进行复制
File.Copy(path, destpath);
//使用File的静态方法删除路径下的一个文件
File.Delete(path);
//使用File的静态方法移动路径下的一个文件
File.Move(path, destpath);
File.ReadAllText(path); //打开一个文本文件*.txt ,读取文件中数据,然后关闭该文件
//写入
File.WriteAllText(path, "要写入文件的字符串"); //创建一个文件,向其中写入数据,如果此路径下有同名文件则会覆

 

PS:对文件进行写入操作,如果路径下有同名文件则会进行覆盖,所以最好进行一次判断,跟用户交互一下在进行覆盖

 

二、实例化FileInfo进行操作

FileInfo myfile = new FileInfo(path); //声明一个对象对某一个文件进行操作
myfile.CopyTo(destpath);  //对文件进行复制操作,复制路径为destpath
myfile.MoveTo(destpath);  //进行移动操作
myfile.Delete();          //进行删除操作

 

获得某一文件或文件夹的详细信息(创建日期,最后一次修改日期等等)

获取一个文件,或者文件夹的详细信息。(创建日期,文件名等)
            FileInfo myfile = new FileInfo(path); //声明一个对象对某一个文件进行操作
            DateTime dt = myfile.CreationTime;  //获取或设置文件/文件夹的创建日期
            string filepath = myfile.DirectoryName; //仅能用于FileInfo,获得完整的路径名,路径+文件名
            bool file = myfile.Exists;              //此属性的值表示文件或文件夹是否存在,存在会返回True
            string fullname = myfile.FullName;     //获取文件或文件夹的完整路径名
            DateTime lastTime = myfile.LastAccessTime; //获取或设置最后一次访问文件或文件夹的时间
            DateTime lastWrite = myfile.LastWriteTime; //获取或设置最后一次修改文件夹或文件夹的时间
            string name = myfile.Name;                 //获取文件名,不能修改哦
            long length = myfile.Length;                  //返回文件的字节大小
            //CreationTime,LastAccessTime,LastWriteTime都是可以被修改的。

 

 如何选择用哪一个类? File or FileInfo

Directory/File只包含静态方法,不能被实例化,只需要提供合适的文件系统对象路径就可以使用,使用效率较高

当只对文件或文件夹执行一次操作,使用这些就很有效。

 

DirectoryInfo/FileInfo 如果使用一个对象执行多个操作,使用这些类就很高效。

因为它们在构造时就读取了文件系统对象的身份验证和其他信息,无论调用了多少方法,都不需要再次读取这些信息。

11 文件操作概述

11.1 驱动器

  在Windows操作系统中,存储介质统称为驱动器,硬盘由于可以划分为多个区域,每一个区域称为一个驱动器。.NET Framework提供DriveInfo类和 DriveType枚举型,以方便在程序中直接使用驱动器。DriveInfo类的常用字段成员有DriveFormat(文件系统格式,如NTFS或FAT32)、DriveType(驱动器类型)、Name(驱动器名)、TotalSize(总空间)、TotalFreeSpace(获得驱动器可用空间)。常用的方法成员有GetDrives(获得可用驱动器列表)。

  DriveType枚举型的枚举值有CDRom(光驱)、Fixed(硬盘)、Network(网络驱动器)和Removeable(软盘或U盘)等。例如,以下代码可以输出每一个硬盘驱动器的剩余空间信息。

DriveInfo[] drivers = DriveInfo.GetDrives();
foreach(DriveInfo driver in drivers)
{
    if(driver.DriveType == DriveType.Fixed && driver.DriveFormat == "NTFS")
    {
        Console.WriteLine("在{0}驱动器上还有{1}字节的剩余空间。", driver.Name, driver.AvailableFreeSpace);
    }
}
Console.ReadLine();

 11.2 目录

  为了方便检索文件,需要在驱动器中先创建目录,然后把文件保存到这个目录中。在Windows操作系统中,目录又称文件夹。每个驱动器都有一个根目录,使用”\”表示,如”C:\”表示C驱动器的根目录。创建在根目录中的目录称为一级子目录。在一级子目录中创建的目录称为二级子目录,依此类推。文件系统的目录结构是一种树形结构。

  .NET Framework提供了Directory类和DirectoryInfo类,以方便在程序中直接操作目录。

  Directory类的常用方法成员有CreateDirectory(创建新目录)、Delete(删除目录)、Exists(判断目录是否存在)、Move(移动目录)、GetFiles(获得目录的文件列表)、GetDirectories(获得子目录列表)等。

  DirectoryInfo类的常用字段成员有Name(提取目录名)、Exists(判断目录是否存在)、Parent(父目录)、Root(根目录)、MoveTo(移动目录)、GetFiles(获得目录的文件列表)、GetDirectories(获得子目录列表)等。例如,以下代码分别展现了Directory类和DirectoryInfo类的基本方法。

Directory.CreateDirectory(@"d:\C#程序设计");
if(Directory.Exists(@"d:\C#程序设计"))
{
    Console.WriteLine("创建成功");
}
Directory.Delete(@"d:\C#程序设计");
if (!Directory.Exists(@"d:\C#程序设计"))
{
    Console.WriteLine("删除成功");
}

DirectoryInfo dir = new DirectoryInfo(@"d:\C#程序设计");
if (!dir.Exists)
{
    dir.Create();
}
else
{
    Console.WriteLine("该目录已经存在");
}

 11.3 文件

  .NET Framework提供了File类和FileInfo类,以方便在程序中直接操作文件。File和FileInfo类位于System.IO命名空间,都可以用来实现创建、复制、移动、打开文件等操作。File类和FileInfo类与Directory类和DirectoryInfo类的工作方式相似。File类是一个静态类,可直接调用其方法成员。FileInfo类不是静态类,需要先创建实例。

  1. 文件类File

  File类的常用方法如表11.1所示。

表11.1 File类的常用方法

常 用 方 法

介 绍

Open()

打开文件

Create()

创建文件

Copy()

复制文件

Delete()

删除文件

Exists()

判断文件是否存在

Move()

移动文件

Replace()

替换文件

AppendAllText()

新建文件并添加文本

ReadAllText()

打开并读取文本内容

  下面通过一个示例演示File类的用法。

(1)  创建一个名为FileCreate的控制台应用程序项目

(2)  修改Program.cs文件中的Main方法的内容如下:        

 //设置所要创建文件的绝对路径
string path = @"d:\test.txt";
//以路径为参数创建文件
File.Create(path);

  代码中变量path给出类文件的路径,利用File类的Create方法创建类该文件。查看D盘根目录,会有一个新的test.txt的文档出现。

  2. 文件信息类 FileInfo

  文件信息类FileInfo与File类不同,它虽然也提供类创建、复制、删除、移动和打开文件的方法,并且帮助创建FileStream对象,但是它提供的仅仅是实例方法。表11.2和表11.3分别展示类FileInfo类的常用字段和方法。

表 11.2 FileInfo类常用字段

常用字段

介绍

Name

提取文件名

Directory

所属目录

Exists

是否存在(继承自父类FileSystemInfo)

Extension

文件扩展名

Length

文件长度

IsReadOnly

是否为只读

表 11.3 FileInfo类常用方法

常用方法

介绍

Open()

打开文件

Create()

创建文件

CopyTo()

复制到新文件

Delete()

删除文件

MoveTo()

移动文件

Replace()

替换文件

EnCrypt()

加密文件

Decrypt()

解密文件

  因此要使用FileInfo类,必须先实例化一个FileInfo对象。FileInfo类的常用方法与File类基本相同。

  与文件类File和文件夹类Directory相比,文件信息类FileInfo和文件夹信息类DirectoryInfo具有其大部分功能。

  * File类和Directory类适合对不同的对象进行单一的处理。此种特殊情况下,静态方法的调用速度比较快,不用进行实例化。

  * FileInfo类和DirectoryInfo类适合用于对同一文件或文件夹进行多种操作的情况。此种情况下,实例化后的对象不需要每次都寻找文件,可以直接对该文件进行操作。

11.4 路径

  每个驱动器包含一个或多个目录,而每个目录又可以包含一个或多个子目录,目录的结构为树形结构。一个文件只能保存在树形结构的某个特定的目录中,文件所在位置为路径。要检索文件时,必须首先确定文件的路径。路径由驱动器盘符、目录名、文件名、文件扩展名和分隔符组成,有两种种表示方法:一种是从驱动器的根目录开始书写,如C:\Windows\System32\notepad.exe,这种路径称为绝对路径;另一种是从当前目录位置开始书写,如System32\notepad.exe(假设当前目录为C:\Windows),这种路径称为相对路径。

  在C#中,使用文件和目录路径时要十分谨慎。C#将反斜杠”\”字符视作转义符,因此当路径表示为字符串时,要使用两个反斜杠表示,例如:

“C:\\Windows\\System32\\notepad.exe”

  另外,C#允许在字符串前添加”@”标志,以提示编译器不要把”\”字符视作转义符,而视作普通字符,例如:

@”C:\Windows\System32\notepad.exe”

  .NET Framework提供了Path类,以帮助在程序中管理文件和目录路径,Path类位于System.IO命名空间,是一个静态类,可以用来操作路径的每一个字段,如驱动器盘符、目录名、文件名、文件扩展名和分隔符等。Path类的常用字段成员有PathSeperator(路径分隔符,如”;”)、DirectorySeparatorChar(目录分隔符,如”\”)、VolumeSeparator(卷分隔符,如”:”)、AltDirectorySeparator(替换目录分隔符,如”/”),常用的方法成员有GetDirectoryName(取目录名)、GetFileName(取文件名)、GetExtension(取文件扩展名)、GetFullPath(取完整路径)、GetTempPath(取操作系统的临时文件路径)等,例如,以下代码表示提取并显示路径中的目录名和文件名。

string path = @"c:\windows\System32\notepad.exe";
Console.WriteLine(Path.GetDirectoryName(path));
Console.WriteLine(Path.GetFileName(path));

  其中,目录名为”C:\Windows\System32”,文件名为”notepad.exe”。

12 文件流概述

  在.NET Framework中,文件和流是有区别的。文件是存储在磁盘上的数据集,它具有名称和相应的路径。当打开一个文件并对其进行读/写时,该文件就称为流(stream)。但是,流不仅仅是指打开的磁盘文件,还可以是网络数据。.Net Framework允许在内存中创建流。此外,在控制台应用程序中,键盘输入和文本显示都是流。流包括以下基本操作:

  * 读取(read):把数据从流传输到某种数据结构中,如输出到字符数组中。

  * 写入(write):把数据从某种数据结构传输到流中,如把字节数组中的数据传输到流中。

  * 定位(seek):在流中查找或重新定位当前位置。

12.1 操作流的类

  1. Stream类

  Stream类是所有流的抽象基类。Stream类的主要属性有CanRead(是否支持读取)、CanSeek(是否支持查找)、CanTimeout(是否可以超时)、CanWrite(是否支持写入)、Length(流的长度)、Position(获取或设置当前流中的位置)、ReadTimeout(获取或设置读取操作的超时时间)、WriteTimeout(获取或设置写操作的超时时间),主要方法有BeginRead(开始异步读操作),BeginWrite(开始异步写操作)、Close(关闭当前流)、EndRead(结束异步读操作)、EndWrite(结束异步写操作)、Flush(清除流的所有缓冲区并把缓冲数据写入基础设备)、Read(读取字节序列)、ReadByte(读取一个字节)、Seek(设置查找位置)、Write(写入字节序列)、WriteByte(写入一个字节)。 

  2. FileStream、MemoryStream和BufferedStream类

  文件流类FileStream以流的形式读、写、打开、关闭文件。另外,它还可以用来操作诸如:管道、标准输入/输出等其他与文件相关的操作系统句柄。

  内存流MemoryStream类用来在内存中创建流,以暂时保持数据,因此有了它就无须在硬盘上创建临时文件。它将数据封装为无符号的字节序列,可以直接进行读、写、查找操作。

  缓冲流BufferedStream类表示把流先添加到缓冲区,再进行数据的读/写操作。缓冲区是存储区中用来缓存数据的字节块。使用缓冲区可以减少访问数据时对操作系统的调用次数,增强系统的读/写功能。

  注意,FileStream类也有缓冲功能,在创建FileStream类的实例时,只需要指定缓冲区的大小即可。

3. StreamReader和StreamWriter类

  流读取器StreamReader类用来以一种特定的编码(如:UTF-8)从字节流中读取字符,流写入器StreamWriter类用来以一种特定的编码(如:UTF-8)向流中写入字符。StreamReader和StreamWriter类一般用来操作文本文件。

4. BinaryReader和BinaryWriter类

  BinaryReader类用特定的编码将基元数据类型读作二进制。BinaryWriter类以二进制形式将基元类型写入流,并支持用特定的编码写入字符串。

12.2 文件流类 FileStream

  文件流类FileStream公开了以文件为主的Stream,既支持同步读/写操作,也支持异步读/写操作,FileStream类的特点是操作字节和字节数组。这种方式不适合操作用字符数据构成的文本文件,适合处理非文本文件。FileStream类提供了对文件的低级而复杂的操作,因此能够实现更多高级的功能。

  下面演示FileStreamWriter类的基本用法:

//要写入文件的字符数组
char[] m_cDataWrite = new char[100];
//包含要写入该流的数据的缓冲区
byte[] m_bDataWrite = new byte[100];           
           
try
{
    //创建d:\file.txt的FileStream对象
    FileStream m_FileStream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate);
    //将要写入的字符串转换成字符数组
    m_cDataWrite = "test filestream".ToCharArray();
 
    //通过UTF-8编码方法将字符数组转成字节数组
    Encoder m_Enc = Encoding.UTF8.GetEncoder();
    m_Enc.GetBytes(m_cDataWrite, 0, m_cDataWrite.Length, m_bDataWrite, 0, true);
 
    //设置流当前位置为文件开始位置
    m_FileStream.Seek(0, SeekOrigin.Begin);
    //将字节数组中的内容写入文件
    m_FileStream.Write(m_bDataWrite, 0, m_bDataWrite.Length);
    if (m_FileStream != null)
    {
        //清除此流的缓冲区,使得所有缓冲的数据都写入到文件中
        m_FileStream.Flush();
        m_FileStream.Close();
    }
}
catch (Exception ex)
{
    Console.WriteLine("There is an IOException");
    Console.WriteLine(ex.Message);
}
Console.WriteLine("Write to File Succeed!");

   代码中首先给出了文件夹的路径,利用Write方法向文件中写入部分字符串。

  下面演示FileStreamReader类的基本用法:

//要写入文件的字符数组
char[] m_cDataWrite = new char[100];
//包含要写入该流的数据的缓冲区
byte[] m_bDataWrite = new byte[100];
 
try
{
    //创建d:\file.txt的FileStream对象
    FileStream m_FileStream = new FileStream(@"d:\file.txt", FileMode.Open);
 
    //设置流当前位置为文件开始位置
    m_FileStream.Seek(0, SeekOrigin.Begin);
    //将文件的内容存到字节数组中(缓存)
    m_FileStream.Read(m_bDataWrite, 0, 100);               
}
catch (Exception ex)
{
    Console.WriteLine("There is an IOException");
    Console.WriteLine(ex.Message);
}
 
//通过UTF-8编码方法将字符数组转换成字符数组
Decoder m_Dec = Encoding.UTF8.GetDecoder();
m_Dec.GetChars(m_bDataWrite, 0, m_bDataWrite.Length, m_cDataWrite, 0);
Console.WriteLine("Read from file Succeed!");
Console.WriteLine(m_cDataWrite);

   代码中首先给出了文件夹的路径,利用Read方法从文件中读取了部分字符串。

12.3 StreamWriter和StreamReader类

应用FileStream类需要许多额外的数据类型转换操作,十分影响效率。StreamWriter类允许直接将字符和字符串写入文件。下面演示其用法:

try
{
    //保留文件现有数据,以追加写入的方式打开d:\file.txt文件
    StreamWriter m_SW = new StreamWriter(@"d:\file.txt", true);
    //向文件写入新字符串,并关闭StreamWriter
    m_SW.WriteLine("Another File Operation Method");
    m_SW.Close();               
}
catch (Exception ex)
{
    Console.WriteLine("There is an IOException");
    Console.WriteLine(ex.Message);
         }
  StreamWriter类提供了另一种从文件中读取数据的方法,下面演示其用法:
try
{
    //以绝对路径方式构造新的StreamReader对象
    StreamReader m_SR = new StreamReader(@"d:\file.txt");
 
    //用ReadToEnd方法将d:\file.txt中的数据全部读入到字符串m_Data中,并关闭StreamReader
    string m_Data = m_SR.ReadToEnd();
    m_SR.Close();
    Console.WriteLine(m_Data);
}
catch (Exception ex)
{
    Console.WriteLine("There is an IOException");
    Console.WriteLine(ex.Message);
}

 12.4 BinaryReader和BinaryWriter类

  BinaryWriter类是除了FileStream和StreamWriter类之外另一种向文件写入数据的方式,与之前两种方式不同,BinaryWriter类将基础数据(如:字符串)以二进制形式写入文件流中,并支持用特定的编码写入。下面演示其用法:

FileStream m_FS = new FileStream(@"d:\data.dat", FileMode.Create);
//通过文件流创建相应的BinaryWriter
BinaryWriter m_BW = new BinaryWriter(m_FS);
for(int i = 0; i < 11; i++)
{
    //向d:\data.dat中写入数据
    m_BW.Write((int)i);
}
 
m_BW.Close();
m_FS.Close();

  代码中首先给出了文件夹的路径,利用BinaryWriter类的Write方法向文件中写入部分二进制字符。该文件是以二进制存储的,因此用记事本打开时,将无法观察到正确的字符,必须使用支持二进制的文本阅读器。

  BinaryReader类是和BinaryWriter类相对应的二进制数据读取类。它用特定的编码将基元数据类型(如:字符串类型)读作二进制值。

FileStream m_FS = new FileStream(@"d:\data.dat", FileMode.Open, FileAccess.Read);
//通过文件流创建相应的BinaryReader
BinaryReader m_BR = new BinaryReader(m_FS);
//从d:\data.dat中读取数据
for(int i = 0; i < 11; i++)
{
    Console.WriteLine(m_BR.ReadInt32());
}
 
m_BR.Close();
m_FS.Close();
 
Console.ReadLine();

  代码中首先给出了文件夹的路径。利用BinaryReader类的ReadInt32方法从文件中读取了所有的二进制字符,并将其读为整数,便于输出。

13 综合应用

13.1 创建日志文件

  日志文件的作用是记录程序运行事件。通常使用文本文件保存数据。日志文件需要程序自动创建,并在指定的事件发生时,使用特定的格式把事件的相关数据记录到日志文件中。

1 技术要点

  * 创建FileStream类实例时,能够通过该类构造函数的参数,指定打开文件的方式和读/写访问的方式。通过指定打开方式,实现日志文件的自动创建。

  * 使用StreamWriter类实例写入文件时,因为部分数据可能由于系统缓慢而未能及时写入,所以在所有的写入操作完成后,需要调用Flush方法将缓冲区的文件内容更新到日志文件中。

  * 使用StreamWriter类实例写入文件时,写入的方式与Console类似,可以使用WriteLine向文件中写入一行文本数据。

2 实现代码

const string _FILENAME = @"..\..\logfile.txt";
static void Main()
{
    //从指定的目录以打开或者创建的形式读取日志文件
    using (FileStream fs = new FileStream(_FILENAME, FileMode.OpenOrCreate, FileAccess.Write))
    {
        //创建日志文件的写入流
        StreamWriter sw = new StreamWriter(fs);
        //向日志文件写入日志信息
        Log("日志文件创建成功", sw);
        //关闭日志文件写入流
        sw.Close();
        Console.WriteLine("日志文件已创建");
    }
 
    //读取并显示日志文件
    using (StreamReader sr = new StreamReader(_FILENAME, Encoding.UTF8))
    {
        string strContent = sr.ReadToEnd();
        sr.Close();
        Console.WriteLine(strContent);
    }
 
    Console.ReadLine();
}
 
static void Log(String message, TextWriter tw)
{
    tw.Write("Log Entry:");
    tw.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
    tw.WriteLine(" :");
    tw.WriteLine(" :{0}", message);
            tw.WriteLine("----------------------------------");
            //将缓冲区中的内容更新到日志文件中
   tw.Flush();
}

 3 源程序解读

  (1)程序引用了System.IO命名空间,在程序头部应添加对该命名空间的引用。

  (2)程序中定义了表示文件路径的常量_FILENAME

  (3)在创建FileStream类实例时,使用FileMode.OpenOrCreate模式,即文件不存在时就创建,存在时就打开已存在的文件。

13.2 对日志文件的读/写操作

  日志文件的读/写和文本文件的读/写方法基本相同,日志文件除了使用StreamReader类和StreamWriter类的实例进行读/写外,还有一些记录事件的要求。例如,在写入数据时使用追加的方式、控制日志文件的大小等。

1 技术要点

  * 使用FileInfo类实例获取日志文件的大小,实现当日志文件的大小超出指定范围时清空日志数据的功能。并使用该类实例的OpenWrite方法,创建FileStream类实例进行写入文件的操作,实现日志文件的自动创建功能。

  * 使用StreamWriter类中定义的Seek方法,将写入位置移动到文件末尾,实现将数据以追加方式写入日志文件的功能。

  * 使用StreamReader类中定义的Peek方法,判断读取器是否已经读到日志文件的末尾。

2 实现代码

//表示日志文件路径及文件名称的字符串
const string FILENAME = @"..\..\logfile.txt";
static void Main(string[] args)
{
    //写入日志信息
    WriteLogFile(FILENAME, "日志信息一");
    //读取日志文件
    Console.WriteLine(ReadLogFile(FILENAME));
    Console.ReadLine();
}
 
static string ReadLogFile(string FileNameWithPath)
{
    //从指定的目录以打开或创建的形式读取日志文件
    FileStream fs = new FileStream(FileNameWithPath, FileMode.OpenOrCreate, FileAccess.Read);
    //定义输出字符串
    StringBuilder output = new StringBuilder();
    //初始化该字符串的长度为0
    output.Length = 0;
    //为上面创建的文件流创建读取数据流
    StreamReader read = new StreamReader(fs);
    //设置当前流的起始位置为文件流的起始点
    read.BaseStream.Seek(0, SeekOrigin.Begin);
    //读取文件
    while(read.Peek() > -1)
    {
        //取文件的一行内容并换行
        output.Append(read.ReadLine() + "\n");
    }
    //关闭释放读数据流
    read.Close();
    //返回读到的日志文件内容
    return output.ToString();
}
 
static void WriteLogFile(string FileNameWithPath, string Message)
{
    //定义文件信息对象
    FileInfo finfo = new FileInfo(FileNameWithPath);
    //判断文件是否存在以及是否大于2K
    if(finfo.Exists && finfo.Length > 2048)
    {
        //删除该文件
        finfo.Delete();
    }
    //创建只写文件流
    using(FileStream fs = finfo.OpenWrite())
    {
        //根据上面创建的文件流创建写数据流
        StreamWriter w = new StreamWriter(fs);
        //设置写数据流的起始位置为文件流的末尾
        w.BaseStream.Seek(0, SeekOrigin.End);
        //写入"Log Entry:"
        w.Write("Log Entry:");
        //写入系统的当前时间并换行
        w.Write("{0} {1} \r\n", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
        //写入日志内容并换行
        w.Write(Message + "\r\n");
        //写入-------------------------并换行
        w.Write("----------------------\r\n");
        //清空缓冲区内容,并把缓冲区内容写入基础流
        w.Flush();
        w.Close();
    }

 运行结果如下:

Log Entry:14:26:09 2017年5月1日

日志信息一

-------------------------------

3 源程序解读

  (1)本示例程序使用写日志文件的WriteLogFile方法向文件中写入一条信息数据,再通过读取日志文件的ReadLogFile方法将日志文件的数据显示出来。本示例程序的流程图如下所示:                                                                                       图1 对日志文件读/写操作示例程序流程图

  (2)在写入日志文件的WriteLogFile方法中,首先打开并判断日志文件的大小是否超出了指定的尺寸。如果超出了指定的尺寸,就先将日志文件删除。然后通过FileInfo类实例的OpenWrite方法创建只写文件流,向该流中写入日志数据。

  (3)在读取日志文件的ReadLogFile方法中,首先创建一个StringBuilder类的实例,用来获取日志文件中的文本数据。接着使用StreamReader类定义的BaseStream属性中的Seek方法,将读取器位置定位在流的开始位置,然后循环读取日志文件中的文本数据,并追加到StringBuilder类实例中,读取过程中,通过StreamReader类中定义的Peek方法判断是否读到文件末尾。

11.3 复制文件

  静态File类中提供了许多操作文件的方法,使用Copy方法复制文件是比较常见的一种操作,调用Copy方法时,可以使用overwrite参数指定是否覆盖文件。

1 技术要点

  * 使用静态类File的Exists方法判断文件是否存在。

  * 使用静态类File的Copy方法实现复制文件的功能,当文件存在时,通过指定override参数覆盖原有文件。

  * 复制文件是系统操作,为了保证程序的稳定性,在复制文件的过程中需要捕获并处理异常。

2 实现代码

//源文件路径及文件名
const string SOURCEFILENAME = @"..\..\myfile.txt";
//目标文件路径及文件名
const string DESTINATIONFILENAME = @"..\..\result.txt";
static void Main(string[] args)
{
    try
    {
        //判断源文件是否存在
        if(!File.Exists(SOURCEFILENAME))
        {
            Console.WriteLine("找不到源文件");
        }
        else if (File.Exists(DESTINATIONFILENAME))
        {
            Console.Write("目标文件已经存在,是否覆盖?(Y/N)");
            if(Console.ReadKey(false).Key == ConsoleKey.Y)
            {
                //覆盖文件
                File.Copy(SOURCEFILENAME, DESTINATIONFILENAME, true);
                Console.WriteLine("复制文件完成");
            }
            else
            {
                Console.WriteLine("取消复制文件");
            }
        }
        else
        {
            //直接复制
            File.Copy(SOURCEFILENAME, DESTINATIONFILENAME);
            Console.WriteLine("复制文件完成");
        }
    }
    catch (Exception)
    {
        Console.WriteLine("复制文件失败");
    }
    Console.ReadLine();
}

 3 源程序解读

  (1)本示例使用File静态类的方法实现文件的复制操作。首先判断源文件是否存在,如果源文件不存在,不作任何处理就返回。接着判断目标文件是否存在,如果目标文件不存在,就直接复制文件,否则就询问是否覆盖现有的目标文件,当用户选择覆盖时,使用源文件覆盖目标文件。

  (2)在复制文件的方法调用时,将复制文件的代码放在一个try...catch结构中,以便捕获并处理复制文件时出现的异常。

  (3)程序执行后,将程序文件所在目录下生成一个名为”result.txt”的文本文件。内容与”myfile.txt”文件一致。

14 小结

  本章主要介绍了.NET中的文件相关的操作。重点介绍了System.IO命名空间下的File类、Directory类、FileInfo类、DirectoryInfo类及FileStream类、StreamReader类、StreamWriter类、BinaryReader类、BinaryWriter类等。并给出了相应的代码示例。

 

附加:

根据文件路径得到内存流的方法

        static MemoryStream GetFileStream(string fileName)
        {
            FileStream sr = File.OpenRead(fileName);
            int byteLen = (int)sr.Length;
            byte[] fileBytes = new byte[byteLen];
            int bytesRead = sr.Read(fileBytes, 0, byteLen);
            MemoryStream stream = new MemoryStream(fileBytes);
            sr.Dispose();
            return stream;
        } 
 
 
posted @ 2021-10-20 15:47  你也很优秀  阅读(10501)  评论(0编辑  收藏  举报