C#小白学习进阶——文件IO

原文参考https://www.cnblogs.com/hellowzl/p/6797556.html

1. 读取磁盘

1.1.驱动器

DriveInfo[] drivers = DriveInfo.GetDrives();//需要提前using System.IO
foreach (DriveInfo driver in drivers)
{
    if (driver.DriveType == DriveType.Fixed && driver.DriveFormat == "NTFS")
    {
        Console.WriteLine("在{0}驱动器上还有{1}G的剩余空间。", driver.Name, (driver.AvailableFreeSpace/Math.Pow(2, 30)).ToString("f2"));//分别获取驱动器的名称以及可用空间,默认用字节数表示,此处换算为G;
    }
}
Console.ReadLine();

1.2. 目录操作

.NET Framework提供了Directory类和DirectoryInfo类。

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

DirectoryInfo类的常用字段成员有Name(提取目录名)、Exists(判断目录是否存在)、Parent(父目录)、Root(根目录)、MoveTo(移动目录)、GetFiles(获得目录的文件列表)、GetDirectories(获得子目录列表)等。

Directory.CreateDirectory(@"d:\C#design");
if (Directory.Exists(@"d:\C#design"))
{
    Console.WriteLine("Create Success");
}
Directory.Delete(@"d:\C#design");
if (!Directory.Exists(@"d:\C#design"))
{
    Console.WriteLine("Delete Success");
}

DirectoryInfo dir = new DirectoryInfo(@"d:\C#design");
int i = Convert.ToInt32(dir.Exists);
Console.WriteLine(i);
if (!dir.Exists)
{
    dir.Create();
    Console.WriteLine(" dir Creating ");
}
else
{
    Console.WriteLine(" dir Existing ");
}

1.3.文件

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

File类的常用方法:

Open()打开文件
Create()创建文件
Copy()复制文件
Delete()删除文件
Exists()判断文件是否存在
Move()移动文件
Replace()替换文件
AppendAllText()新建文件并添加文本
ReadAllText()打开并读取文本内容

创建文件:

string path = @"d:\c#_test.txt";
File.Create(path);
if (File.Exists(@"d:\c#_test.txt"))
{
    Console.WriteLine("File already exists");
}
else
{
    Console.WriteLine("File reading error");
}

FileInfo类常用字段

Name提取文件名
Directory所属目录
Exists是否存在(继承自父类FileSystemInfo)
Extension文件扩展名
Length文件长度
IsReadOnly是否为只读

FileInfo类常用方法

Open()打开文件
Create()创建文件
CopyTo()复制到新文件
Delete()删除文件
MoveTo()移动文件
Replace()替换文件
EnCrypt()加密文件
Decrypt()解密文件

操作实例:

FileInfo file_info = new FileInfo(@"d:\c#_test.txt");
Console.WriteLine("文件拓展名:{0}",file_info.Extension);
Console.WriteLine("文件目录:{0}", file_info.Directory);
Console.WriteLine("文件长度:{0}", file_info.Length);
//file_info.CopyTo(@"d:\C#design\c#_test2.txt");
DateTime dt = file_info.CreationTime;  //获取或设置文件/文件夹的创建日期,可被修改
string filepath = file_info.DirectoryName; //仅能用于FileInfo,获得完整的路径名,路径+文件名
bool file = file_info.Exists;              //此属性的值表示文件或文件夹是否存在,存在会返回True
string fullname = file_info.FullName;     //获取文件或文件夹的完整路径名
DateTime lastTime = file_info.LastAccessTime; //获取或设置最后一次访问文件或文件夹的时间,可被修改
DateTime lastWrite = file_info.LastWriteTime; //获取或设置最后一次修改文件夹或文件夹的时间,可被修改
string name = file_info.Name;                 //获取文件名,不能修改
long length = file_info.Length;                  //返回文件的字节大小
FileStream file_stream = file_info.Create();
Console.WriteLine(file_stream);

二者比较

Directory/File只包含静态方法,不能被实例化,只需要提供合适的文件系统对象路径就可以使用,使用效率较高
当只对文件或文件夹执行一次操作,使用这些就很有效。
DirectoryInfo/FileInfo 如果使用一个对象执行多个操作,使用这些类就很高效。
因为它们在构造时就读取了文件系统对象的身份验证和其他信息,无论调用了多少方法,都不需要再次读取这些信息。

1.4.路径操作

Path类的常用字段成员有PathSeperator(路径分隔符,如”;”)、DirectorySeparatorChar(目录分隔符,如”\”)、VolumeSeparator(卷分隔符,如”:”)、AltDirectorySeparator(替换目录分隔符,如”/”),常用的方法成员有GetDirectoryName(取目录名)、GetFileName(取文件名)、GetExtension(取文件扩展名)、GetFullPath(取完整路径)、GetTempPath(取操作系统的临时文件路径)等

string path = @"d:\c#_test.txt";
Console.WriteLine(Path.GetDirectoryName(path));
Console.WriteLine(Path.GetFileName(path));
Console.WriteLine(Path.GetExtension(path));

2.文件流

2.1.操作流的类

  1. Stream类

Stream类是所有流的抽象基类。

  1. FileStream、MemoryStream和BufferedStream类

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

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

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

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

  1. StreamReaderStreamWriter

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

  1. BinaryReader和BinaryWriter类

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

2.2.文件流的类

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

1.写入内容到TXT文件:

//要写入文件的字符数组
char[] m_cDataWrite = new char[10000];
//包含要写入该流的数据的缓冲区
byte[] m_bDataWrite = new byte[10000];

try
{
    //创建d:\file.txt的FileStream对象
    FileStream m_FileStream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate);
    //将要写入的字符串转换成字符数组
    string str = @"1创建字符数组内存和缓冲区内存。\n2创建文件的stream对象。\n3输入对应字符串并转化为char类型。\n" +
        "4字符串的编码,将char写入缓冲区。\n5设置2中文件流写入初始位置。\n6写入4中缓冲区的对象。\n7清除缓冲关闭文件";
    m_cDataWrite = str.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!");

2读取TXT内容:

//要写入文件的字符数组
char[] m_cDataWrite = new char[10000];
//包含要写入该流的数据的缓冲区
byte[] m_bDataWrite = new byte[10000];

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, 10000);
}
catch (Exception ex)
{
    Console.WriteLine("There is an IOException");
    Console.WriteLine(ex.Message);
}

//通过UTF-8编码方法将字符数组转换成字符数组,
//1打开文件,2设置初始位置,3内容读到缓冲区,4,对缓冲区内容解码。
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);

2.3StreamWriter和StreamReader

//StreamWriter写文件:
try
{
    //保留文件现有数据,以追加写入的方式打开d:\file2.txt文件
    StreamWriter m_SW = new StreamWriter(@"d:\file2.txt", true);
    //向文件写入新字符串,并关闭StreamWriter
    m_SW.WriteLine(@"1创建字符数组内存和缓冲区内存。\n2创建文件的stream对象。\n3输入对应字符串并转化为char类型。\n" +
        "4字符串的编码,将char写入缓冲区。\n5设置2中文件流写入初始位置。\n6写入4中缓冲区的对象。\n7清除缓冲关闭文件");
    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:\file2.txt");

    //用ReadToEnd方法将d:\file2.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);
}

2.4BinaryReader和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();

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

m_BR.Close();
m_FS.Close();

3.日志综合运用

自定义日志文件的读写操作:

static void Main(string[] args)
{
    //表示日志文件路径及文件名称的字符串
    const string FILENAME = @"..\..\logfile.txt";

    //写入日志信息
    //1-file_info读取对象文件:file_info = FileInfo(path)2-创建读写文件流fs = file_info.OpenWrite()3-写数据流w = StreamWriter(fs)4-w.Write("abc")
    WriteLogFile(FILENAME, "日志信息1一");
    //读取日志文件
    //1-创建读写文件流fs = FileStream(path)2-定义输出字符串output = StringBuilder()3-读数据流read = StreamReader(fs);4output.Append(read.ReadLine())
    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();
    }
}

附加

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

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;
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值