IO 101:TextWriter,FileStream和StreamWriter之间的主要区别是什么?

Nan*_*ada 40 .net c# io .net-3.5

让我首先道歉,如果这个问题听起来对你们中的经验丰富的程序员来说可能听起来很业余,那就是我在工作中一直有很多关于这方面的争论,所以我真的想要直截了当,这就是为什么我依赖在stackoverflow社区,一劳永逸地解决这个问题:)

所以,一方面根据MSDN,我们有:

TextWriter类

表示可以编写一系列连续字符的编写器.这个类是抽象的.

FileStream类

在文件周围显示Stream,支持同步和异步读写操作.

StreamWriter类

实现TextWriter,以便以特定编码将字符写入流中.

另一方面,很明显它们都属于System.IO但是考虑到MSDN示例混合其中的一些,我仍然没有达到非常期望的a-ha时刻.

任何评论都会超过赞赏,非常感谢!

lav*_*nio 60

Streams处理字节,Writers处理字符.

字节!=字符.字符可能需要多个字节来表示.从字符到字节的映射称为编码.

A FileStream指的是写入文件的字节,类似于a如何MemoryStream引用写入内存缓冲区的字节.为了将字符写入流,您需要将它们转换为字节串.这就是StreamWriter进入游戏的地方.它需要一系列字符和一个编码,并将其转换为字节序列.

A TextWriter是所有作者必须遵守的接口(井,抽象基类).它具有基于字符的所有操作.bytes的等价物是Stream抽象基类.

事情也朝着相反的方向发展.有一个TextReader抽象基类,描述了如何从某处读取字符,以及a StreamReader,它允许您从提供编码的面向字节的流中读取字符 - 但这次用于反向,将任何多字节序列聚合为单个适当的字符.

A Stream可用于读取和写入,因为字节是I/O操作中使用的最低级别的项目.

  • TextWriter不是一个接口,它是一个抽象的基类. (6认同)

Ins*_*ter 10

我总是发现最好的办法就是看看它们提供的方法以及如何构建它们.这几乎总是主要的,如果不是唯一的,我在使用API​​时关心的事情.我如何构建它以及它能做什么?

您无法实例化TextWriter.这是抽象的.这告诉我它所服务的唯一真正目的是抽象.如果你编写一个将任何类型的编写器作为参数的函数,那么你很有可能只需要将TextWriter变得更加通用.

您可以实例化一个StreamWriter,它就像它所说的一样,它写入流.这意味着它需要一个流来完成任何真正的写作.一旦你拥有了那个流,你就可以做各种简洁的事情,比如一次写一行,而不是像直接在流上那样处理单个字符(或者说字节).

所以基本上,你得到一个流,所以你可以将它提供给StreamWriter(或读者).如果您正在编写文本,您可能不希望直接使用流,只需要使用字符数组而不是字符串.

FileStreams可以方便地直接从File和FileInfo类实例化,在我的用法中,这就是它们通常被实例化的方式.获取文件(我喜欢使用FileInfo)并调用OpenWrite().将它传递给StreamWriter(这只是一种TextWriter),你就可以了.

概括:当你想弄清楚一个类时,试着看看你如何实例化它以及它可以做什么.这通常会清除很多.


Nad*_*zie 6

"Stream"和"Writer/Reader"之间有明显的区别.

流是字节级表示,并且实际上是可以以各种方式实现的抽象概念.例如,您有一个FileStream和一个MemoryStream.这两者都是字节流,但它们的存储方式不同.

作家和读者为您提供了一种处理流,添加和提取数据的方法.

对于您的特定示例,TextWriter是一个抽象类,它按顺序将字符写入流.它有几个实现(StreamWriter,StringWriter),它们在不同的上下文中很有用.你可以使用当时有意义的东西.但是,对于几个API,所需要的只是TextWriter,或称为"Write"或"WriteLine"的东西.如果您的编写器用于将内容放入字符串,某些任意内存或文件中,那么这些API就不是问题了.


Man*_*ham 5

Stream是表示一系列字节的抽象基类。

  • MemoryStream是内存中保存的字节流,由数组支持。

  • FileStream是文件中的字节流,通常由磁盘上某处的文件句柄支持。

文本字符本身由字节组成,单个字符可以是多个字节,具体取决于编码。有一些标准类使用特定编码将文本读取和写入到不同的源。

TextWriter是一个抽象基类,用于将文本字符写入目的地。

  • StreamWriter将文本字符(转换为字节)写入字节流。
  • StringWriter将文本字符写入字符串(通过 StringBuilder)。

TextReader是用于从源读取文本字符的抽象基类。

  • StreamReader从字节流中读取文本字符(从字节转换而来)。
  • StringReader从字符串中读取文本字符。

StreamTextWriterTextReader都是抽象基类,因此它们从不直接使用,而是通过如上所述的实现来使用。但是,您将在方法定义中看到基类,以便可以使用不同的实现,包括您自己的自定义实现(如果需要)。抽象类与接口类似,但实际上可以定义方法的逻辑,可以重用这些方法,而无需每个实现都重复相同的基本代码。