首页 > 编程语言 >重学c#系列—— IO流[三十四]

重学c#系列—— IO流[三十四]

时间:2023-02-04 18:22:29浏览次数:46  
标签:文件 IO 读取 三十四 字符 c# io new 字节

前言

简单介绍一下io流。

以前写过两篇,里面是java 语言写的,简单介绍了一下io流,这里是对io流的整理。

https://www.cnblogs.com/aoximin/p/12007925.html

https://www.cnblogs.com/aoximin/p/12044270.html

这里说一下一个经验,仅献给入门的人。

刚写代码进行io流读取或者写入的时候,有一个思维去考虑这个io流是怎么从磁盘读取的或者怎么从内存读取的,

这个想法是没错的,但是不是应用层面考虑的东西,是操作系统和硬件的结合(操作系统篇会介绍全面),这会使人脑复杂,下面请以应用层面考虑问题。

正文

在io流中有几个概念必须知道:

  1. 字符流

  2. 字节流

  3. 节点流

  4. 处理流

如果不清楚这些概念,那么你就需要看完这一篇回忆一下以前的基础。

在java中,比如一个文件的读取,分为FileInputStream 和 FileOutputStream。

但是在c# 是这样设计的,文件流就是文件流, 没有把输入和输出分开。

但是一般情况下,我们要么读,要么写,这样复杂度就更低了。

比如我们创建一个文件流:

FileStream F = new FileStream("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);

这里面有几个参数,分别是: 地址,FileMode,FileAccess,FileShare

那么看下FileMode 里面有什么吧。

  public enum FileMode
  {
    CreateNew = 1,
    Create = 2,
    Open = 3,
    OpenOrCreate = 4,
    Truncate = 5,
    Append = 6,
  }

可以直接参考这个文档:

https://learn.microsoft.com/zh-cn/dotnet/api/system.io.filemode?view=net-7.0

文档中描述的比较清楚,就不赘述了。

FileAccess 第二个参数是FileAccess

  [Flags]
  public enum FileAccess
  {
    Read = 1,
    Write = 2,
    ReadWrite = Write | Read, // 0x00000003
  }

权限,是读,写,或者读和写。

第4个参数是FileShare:

https://learn.microsoft.com/zh-cn/dotnet/api/system.io.fileshare?view=net-7.0

就是一些共享状态,比如我这个文件在读了,另外的文件是否可以读。

这个可以根据自己的应用需求去处理。

然后我们一般情况下是会使用一个叫做File.create 方式去创建文件流的。

那么它的默认状态是:

public static FileStream Create(string path, int bufferSize)
            => new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize);

所以这里要知道的是,如果我们使用File.create得到的FileStream。

如果文件存在呢,那么文件就会从头开始写,这点是新手值得注意的地方。

知道了前面这些基础概念后,那么就可以往下走了。

文件

我们在应用层面向对象变成,那么我们要做的是什么?

要做的就是如果将这个文件,如果抽象成一个对象。

那么我们编程使用什么方式可以抽象成一个对象呢?

static void Main(string[] args)
{
	FileInfo a = new FileInfo("a.txt");

	Console.ReadKey();
}

有一个FileInfo 供我们使用,这样就可以将文件映射成一个对象了。

一个FileInfo 我们可以拿到上面这些信息。

还可以对文件进行操作:

比如:

这些是操作文件的,那么有个问题啊,那就是如何操作目录呢?

DirectoryInfo a = new DirectoryInfo("c://a");

目录有目录的信息。

这里值得注意的地方是,有些变成编程语言的思想是把目录看出文件,然后再文件对象中就可以创建出目录。

我们写代码的时候了解一下编程语言的思维就好了。

io 流的分类

从操作数据单位不同分为:

  1. 字节流

  2. 字符流

字节流-它包括流,FileStream,MemoryStream 和 BufferedStream。

字符流-它包括TextReader-TextWriter,StreamReader,StreamWriter和其他流。

通过流的流向不同分为:

  1. 输入流

  2. 输出流

通过流的角色的不同分为:

  1. 节点流

  2. 处理流/包装流

这个下面都会介绍到。

字符流

简单介绍一下字符流,这里面有一个问题。

我们都知道,在文件存储的最小单位是字节。

总没有听说,一个文件存一个bit吧。字节是存储的最小单位。

那么就有一个问题啊,比如我们io,那么最小有效单位应该也是字节吧。

传输的也是字节对吧,建立在这个理论基础上,那么我们的字节流是合情合理的。

这个是传输层面的意义了。

那么为什么有字符流呢?因为我们发现字符格式有utf-8,ASCII等。

比如说utf-8,汉字是3个字节。比如一个我,那么应该读取3个字节,而不是一个字节才是有意义的对吧。

那么就有字符流了。字节流是每次都是读取一个字节,字符流每次读取的那么就可能是一个字节或者两个或者3个,看编码形式。

static void Main(string[] args)
{
	TextReader textReader = new StreamReader("a.txt", Encoding.ASCII);
	Console.ReadKey();
}

StreamReader 是文件字符流。TextReader 是其基类。

所有的字符流的读取基类是TextReader。

StreamReader 是对文件的字符流的读写,那么StringReader 是对内存的读写了。

其他的就不演示了,自我熟悉就好,c# 官方文档更加专业。

看文档就好:

https://learn.microsoft.com/zh-cn/dotnet/api/system.io.stringreader?view=net-7.0

节点流和处理流

什么是节点流呢:

节点流是从一个特定的数据源读写数据,如:StreamReader、FileStream。

就是直接从一个数据源进行读写。

那么什么是处理流呢?

处理流也叫做包装流,是连接在存在的流之上,为程序提供更为强大的读写功能,如BufferedStream。

static void Main(string[] args)
{
	var  a= File.Create("a.txt");
	BufferedStream stream = new BufferedStream(a);
	Console.ReadKey();
}

二进制处理流

二进制处理流是这样的,其实很像字符流。

比如说,我们除了存字符,我们还可以存数字对吧。

还可以存bool类型。

那么其实就是如果是读取int,那么就是读取4个字节,读取bool 就是读取两个字节。

static void Main(string[] args)
{
	MemoryStream aStream = new MemoryStream();
	BinaryWriter writer = new BinaryWriter(aStream);
	writer.Write(10);
	writer.Write(20);
	Console.Read();
}

读取的时候也是一样的。

也没什么好记的,主要是整理一些概念,一些实现原理,会查文档就好。

标签:文件,IO,读取,三十四,字符,c#,io,new,字节
From: https://www.cnblogs.com/aoximin/p/17092082.html

相关文章

  • P5572 [CmdOI2019]简单的数论题
    [CmdOI2019]简单的数论题题意即求:\[\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi\left(\dfrac{\operatorname{lcm}(i,j)}{\gcd(i,j)}\rig......
  • Mac上Homebrew常用命令
    Mac上Homebrew常用命令官方网址https://brew.sh/常用命令安装(官方方法)/bin/bash-c"$(curl-fsSLhttps://raw.githubusercontent.com/Homebrew/install/HEAD/inst......
  • C++future promise
    Afutureisanobjectthatcanretrieveavaluefromsomeproviderobjectorfunction,properlysynchronizingthisaccessifindifferentthreads.provider比较......
  • Android笔记--内容提供者+Server端+Client端
    什么是内容提供者ContentProvider为App存取内部数据提供的统一的外部接口,让不同的应用之间得以实现数据共享ClientApp端用户输入数据的一端,或者说是用户读取到存储的数......
  • TMC5160步进电机驱动芯片开发使用笔记-1
    内容主要来自TMC5160数据手册,个人的理解简单做下笔记:TMC5160做为驱动芯片,单片机作为控制器,控制一个或多个5160;站在应用的角度去分析,不涉及过多电子方面;    TMC5......
  • Fabric2.x中Raft共识算法核心数据结构
    一、共识算法可插拔的代码体现Chain接口HyperledgerFabric的共识算法是可插拔的,在代码上体现为Chain接口,所有不同的共识算法均可根据Chain接口进行具体实现,目前fabric支......
  • WC2023(授课与讨论7)
    FabulousFungusFrenzy(3)将过程逆序,\(1\)操作不变,\(2\)操作即将与模板矩阵匹配的子矩形变为通配符借助\(1\)操作,可以在\(2(n+m)\)次操作内交换两个位置在此基础上,不断......
  • 保持cerebro的通知及查询Node的box_type
    今天介绍通过chrome谷歌浏览器,改进cerebro的两个小功能. 1.保持cerebro的通知显示.默认cerebro的通知显示只有几秒,还没有看清楚是什么问题,通知框就消失了.尤其是是......
  • [Docker] Build multi stage image
    ExistingDockerfileDockerfile:FROMpython:3ENVPYBASE/pybaseENVPYTHONUSERBASE$PYBASEENVPATH$PYBASE/bin:$PATHRUNpipinstallpipenvWORKDIR/tmpCOP......
  • CF765F Souvenirs 题解
    Preface在会压位Trie的前提下,本题最好想的做法应该是压位Trie+回滚莫队,可是竟然没人写这个做法的题解?Solution我们先转化题意:设\(a_i\)在\([l,r]\)中的前驱后继......