C#--IO

常见文件操作类,大致可分为操作目录类,操作文件类,操作路径类

1.File、FileInfo、FileStream属于操作文件的类

2.Directory、DirectoryInfo属于操作目录的类

3.StreamReader、StreamWriter类属于操作文本文件的类

4.Path类属于操作文件路径的类

首先介绍对文件和文件夹的操作,也就是对文件和对文件夹进行创建,复制,删除等操作,下面分别介绍两种不同的方式,处理文件:File类和FileInfo类;处理文件夹:Director类(文件夹)和DirectorInfo类

处理文件:File类对文件是提供的静态方法,也就是可以直接用类调用方法来进行创建,移动,复制,删除等,具体如下(注意引入using System.IO命名空间),而FileInfo类需要实例化对象后使用,该例子只书写了创建,该类还有其它方法请参考File 类 (System.IO) | Microsoft Learn

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IO的一系列操作
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //这里都是生成在Debug目录下的绝对路径
            File.Create(@"test");//创建一个名为test文件,返回值是FileStream
            File.CreateText(@"testText");//创建一个名为testText文本文件,返回值是StreamWrite

            FileInfo fi1 = new FileInfo("testFileInfo");//声明一个FileInfo对象,如果在该路径下存在testFileInfo的文件,那会fi1对象就会接收testFileInfo文件
                                                        //这里可以把它理解为把路径当作对象,如果不存在的话,除了creat以外,因为对象是空的就不会做任何操作
            fi1.Create();//同上方一样
            FileInfo fi2 = new FileInfo("testFileInfoText");
            fi2.CreateText();           
        }
    }
}

File和FileInfo也是会在使用场景上有一点区别的,例如如果应用程序在文件上需要执行多次操作时候,选择FileInfo比较好一点,因为一但创建了对象,就可以直接使用对象对文件进行操作,不需要像File那样每次操作都需要输入路径,从而节省时间;如果执行一些单一的调用方法,就建议使用File类了,因为可以不用实例化。文件夹操作同理

在IO方面最关键的就是读和写,File在读取上就会提供

File.ReadAllText(),File.ReadAllLines(),File.ReadAllBytes()等方法,在写入上也会提供File.WriteAllText(),File.WriteAllLines(),File.WriteAllBytes()等方法,但是FileInfo就不存在这些方法,无论是写入还是读取,这些方法都是先将内容先存放在内存中,如果文件过大,就会导致内存不足的情况,这个时候就不能使用File类提供的这些方法直接进行读取,这个时候就需要用到流

流的基本概念:可以把需要读取或者写入的数据当作是水,那么流就相当于是一个别人做好的水管,当数据需要从硬盘读取到内存中时,数据(水)就通过流(水管)持续传输到内存(指定地方)去,那我们不需要知道水管怎么做的,只需要只要水的起点和终点,然后用水管把起点和终点连接上即可,注意这个水管是单向运输的,也就是说一个水管只能负责一个方向的运输(也就是输出流和输入流,以内存为第一人称,数据从内存向外流的称为输出流,数据由外向内存流的称为输入流

在了解完流的基本概念后,就介绍FileStream类,也就是微软官方提供的用于数据传输的"水管",

FileStream类有很多重载的构造方法,其中最常用的是带有三个参数的构造方法。

FileStream(string path,FileMode mode,FileAccess access)

第一个参数path,是文件路径名

第二个参数mode,表示如何打开或创建文件:分别是打开,创建和追加(有FileMode.Open,FileMode.Create,FileMode.Append)

第三个参数access,用于确定FileStream对象访问文件的方式,分别是:,FileAccess.Read,FileAccess.Write,FileAccess.ReadWrite

参考这篇博客(7条消息) 【C# 教程系列第 19 篇】FileMode,FileAccess 的参数释义_Allen Su的博客-CSDN博客_c# fileaccess

创建流:

(1)创建流直接使用其构造函数:FileStream fs=new FileStream(string path,FileMode mode,FileAccess access)

(2)在使用File和FileInfo时,可以注意到他们的定义

都提到了帮助创建FileStream对象,这是因为像诸如 File.Create()或者FileInfo对象.Create()的返回值的类型都是FileStream;当我在查询资料时,就在思考,那像这样直接使用流的构造函数new FileStream()和File.Open()(因为这个函数也是返回的FileStream类型,并且这个函数也会设置文件的Filemode,)这两者有什么区别呢,事实上没区别

再者像FileStream fs1= File.Create(@"fsTest");

和FileStream fs2 = new FileStream("fsTest", FileMode.Create);你会发现,fs1对象的并没有写明该对象的操作指定文件的打开方式(也就是FileMode)和访问权限(FileAccess)但是经过测试,fs1默认的是FileMode.Creat和FileAccess.ReadWrite

说完创建FileStream的两种方式后,再看看怎么使用它,在创建对象的时候已经声明了打开方式和访问权限,这与你接下来想要做的操作有关;例如

当想要读取文件也就是输入流的时候,这时声明对象是

 FileStream fs = new FileStream(@"fsTest", FileMode.Open);//如果文件不存在,则会抛出异常。
 //或者
 FileStream fs = new FileStream(@"fsTest", FileMode.OpenOrCreate);//打开或者新建文件夹,如果文件存在,则打开文件,把指针指到文件的开始;如果文件不存在,则新建文件。

当想要写入文件,也就是输出流时

FileStream fs = new FileStream(@"fsTest", FileMode.CreateNew);//创建新的文件,如果文件已存在,则会抛出异常。
FileStream fs = new FileStream(@"fsTest", FileMode.Create);//创建新的文件,如果文件已存在,则覆盖;如果文件不存在,则创建新的
FileStream fs = new FileStream(@"fsTest", FileMode.Truncate);//如果文件存在,则打开文件,清除这个文件中的内容,把指针指到文件的开始,保留最初文件的创建日期(重写);如果文件不存在,则抛出异常。
FileStream fs = new FileStream(@"fsTest", FileMode.Append);//追加,如果文件存在,则打开文件,把指针指到文件的末尾;如果文件不存在,则新建文件。

这也不是绝对的,因为同样你可以用FileMode.Open打开文件后,再写入内容进去,不过按照一般的情景,当我们需要读取文件时,肯定是想要打开某个文件,然后读取,总不会创建一个新文件或者说把这个已存在的文件覆盖了再进行读取,写入文件同样,肯定是要么创建一个新文件开始写入,要么在已经有的文件基础上进行追加写入,总不会在一个已经存在的文件上从头开始写入(这两种情景就对应上方的FileMode)

注意的是上方这两种我都没有写FileAccess,那就是默认可读可写的,当写FileAccess时要注意搭配的合理,比如我想要写文件,可是声明对象的时候却给FileAccess.Read的只读权限就会出现搭配不合理的情况

一般用FileStream类进行读取时,使用的是ReadByte()方法一个字节一个字节的读取,这样就读取得比较慢,适合小文件,那么读取大文件时就需要使用Read()方法,第二个方法的参数是(数组,第几个字节开始,第几个字节结束),具体内容查阅相关资料,写也同样如此,附上siki学院的视频地址504-优化读取和写入流_哔哩哔哩_bilibili

注意在使用流的时候要注意关闭,如果不关闭,该流会一直占用程序,直到应用程序被关闭,举个例子就相当于从水(数据)从a点到b点的一个A水管(流)打开了,当水完全从a点到b点后,虽然没有水了,但是水管(流)一直还开着,我想把b点的水运到a点,由于水管的单向性(输入/输出流)就需要重新用另一根B水管,可是之前的A水管还开着就不能重新接另一根水管,这时就需要把A水管关闭了才能使用B水管

像这样就会报错

 byte[] bytes = new byte[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };  
 FileStream fs = new FileStream(@"fsTest", FileMode.Open);
 fs.Write(bytes, 0, bytes.Length);
 FileStream fs2 = new FileStream(@"fsTest", FileMode.Open);

因此解决办法

(1)使用using,将创建文件流对象的过程写在using当中,会自动帮助我们释放资源;

byte[] bytes = new byte[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };
using (FileStream fs = new FileStream(@"fsTest", FileMode.Open))
{
    fs.Write(bytes, 0, bytes.Length);
}
FileStream fs2 = new FileStream(@"fsTest", FileMode.Open);

(2)手动使用close()关闭

byte[] bytes = new byte[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };
FileStream fs = new FileStream(@"fsTest", FileMode.Open);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
FileStream fs2 = new FileStream(@"fsTest", FileMode.Open);

在上方除了FileStream类(对文件进行读取和写入)以外,还有两个类是专门负责文本文件的读取和写入的那就是StreamReader,StreamWriter

获取StreamReader的方式也同样有很多,例如

 StreamReader reader = new StreamReader(@"fsTest");//直接使用构造函数

FileStream fs = new FileStream(@"fsTest", FileMode.Open);//用FileStream对象
StreamReader reader2 = new StreamReader(fs);

FileInfo fi2 = new FileInfo("testFileInfoText");//用FileInfo对象
StreamReader reader3=fi2.OpenText();

StreamReader类中就有许多读取的方法ReadLine()一行一行读取,Read()一个字符一个字符读取,具体自行查阅资料,附上siki学院教程505-文本读取和写入流StreamReader和StreamWriter_哔哩哔哩_bilibili

StreamWriter和StreamReader几乎一样,就不一一赘述了,其实在学习完了FileStream后就会发现这两个类与FileStream大同小异,无非这两个是专门对文本文件操作的类,不过应该注意使用完后还是要关闭流

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值