C# IO 101:TextWriter、FileStream 和 StreamWriter 之间的主要区别是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1010555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IO 101: Which are the main differences between TextWriter, FileStream and StreamWriter?
提问by Nano Taboada
Let me first apologize if this question could sound perhaps sort of amateurish for the seasoned programmers among you, the thing is I've been having many arguments about this at work so I really want to get this straight and that's basically why I'm relying on the stackoverflow community to get this settled once and for all :)
如果这个问题对于你们中经验丰富的程序员来说听起来可能有点业余,让我首先道歉,问题是我在工作中一直对此有很多争论,所以我真的很想弄清楚这基本上就是我依赖的原因在stackoverflow社区上一劳永逸地解决这个问题:)
So, on the one hand according to MSDN, we have:
因此,一方面根据 MSDN,我们有:
TextWriter Class
Represents a writer that can write a sequential series of characters. This class is abstract.
FileStream Class
Exposes a Stream around a file, supporting both synchronous and asynchronous read and write operations.
StreamWriter Class
Implements a TextWriter for writing characters to a stream in a particular encoding.
TextWriter 类
表示可以编写一系列连续字符的作者。这个类是抽象的。
文件流类
围绕文件公开 Stream,支持同步和异步读写操作。
StreamWriter 类
实现一个 TextWriter,用于以特定编码将字符写入流。
On the other hand it's evident they all belong to System.IO but given that MSDN examples kind of mix some of them, I'm still not reaching the much desired a-ha moment.
另一方面,很明显它们都属于 System.IO,但考虑到 MSDN 示例混合了其中的一些,我仍然没有达到非常想要的 a-ha 时刻。
Any comment would be more than appreciated, thanks much in advance!
任何评论将不胜感激,非常感谢!
采纳答案by lavinio
Streams handle bytes, Writers handle characters.
流处理字节,写入器处理字符。
Bytes != characters. A character may take more than one byte to represent. The mapping from characters to bytes is called an encoding.
字节 != 字符。一个字符可能需要一个以上的字节来表示。从字符到字节的映射称为编码。
A FileStream
refers to the bytes being written to a file, similar to how a MemoryStream
refers to the bytes written to an in-memory buffer. In order to write characters to a stream, you'd need to convert them to a string of bytes. That's where a StreamWriter
comes in to play. It takes a sequence of characters and an encoding, and turns it into a sequence of bytes.
AFileStream
指的是写入文件的字节,类似于 aMemoryStream
指的是写入内存缓冲区的字节。为了将字符写入流,您需要将它们转换为字节字符串。这就是 aStreamWriter
发挥作用的地方。它采用字符序列和编码,并将其转换为字节序列。
A TextWriter
is an interface (well, abstract base class) that all of the Writers must adhere to. It has all operations based on characters. The equivalent for bytes is the Stream
abstract base class.
ATextWriter
是所有 Writer 都必须遵守的接口(好吧,抽象基类)。它具有基于字符的所有操作。字节的等价物是Stream
抽象基类。
Things also go in the opposite direction. There is a TextReader
abstract base class, describing how to read characters from somewhere, and a StreamReader
, which allows you to read characters from a byte-oriented stream supplying an encoding - but this time used in reverse, to aggregate any multi-byte sequences into single characters where appropriate.
事情也朝着相反的方向发展。有一个TextReader
抽象基类,描述如何从某处读取字符,还有一个StreamReader
,它允许您从提供编码的面向字节的流中读取字符 - 但这次反向使用,将任何多字节序列聚合为单个适当的字符。
A Stream
can be used for both reading and writing, since bytes are the lowest-level items used in I/O operations.
AStream
可用于读取和写入,因为字节是 I/O 操作中使用的最低级别的项目。
回答by scottm
The FileStreamclass manages getting a handle to a file and opening it for reading or writing and other filesystem functions. BinaryWriterwrites binary data to a stream and StreamWriterwrites character data to a stream. They both can use a FileStream object to write binary or character data to files.
该的FileStream类管理得到一个句柄到一个文件,并打开它读取或写入和其它文件系统函数。BinaryWriter将二进制数据写入流,StreamWriter将字符数据写入流。它们都可以使用 FileStream 对象将二进制或字符数据写入文件。
TextWriter is the base class that StreamWriter inherits from. A TextWriteris intended to take a type and output a string using its Writemethod. StreamWriter's implementation of the TextWriter.Write method writes a string, or character data, to a stream. BinaryWriter does not inherit TextWriter because it does not write character data to a stream.
TextWriter 是 StreamWriter 继承的基类。甲的TextWriter旨在采取类型和输出使用其的字符串写入方法。StreamWriter 的 TextWriter.Write 方法实现将字符串或字符数据写入流。BinaryWriter 不继承 TextWriter,因为它不会将字符数据写入流。
回答by Nader Shirazie
There's an obvious difference between a "Stream" and a "Writer/Reader".
“Stream”和“Writer/Reader”之间有明显的区别。
A stream is a byte level representation, and is really an abstract concept that can be implemented in a variety of ways. For example, you have a FileStream and a MemoryStream. Both those are streams of bytes, but they are stored differently.
流是字节级别的表示,实际上是一个可以通过多种方式实现的抽象概念。例如,您有一个 FileStream 和一个 MemoryStream。两者都是字节流,但它们的存储方式不同。
Writers and Readers give you a way to process streams, adding and extracting data from them.
Writers 和 Readers 为您提供了一种处理流、添加和从中提取数据的方法。
For your particular examples, TextWriter is an abstract class that writes characters to a stream sequentially. It has several implementations (StreamWriter, StringWriter) that do are useful in different contexts. You would use whichever makes sense at the time. For several APIs however, all that is needed is a TextWriter, or something to call "Write" or "WriteLine" on. It isn't a concern of those APIs if your writer is used to put stuff into a string, some arbitrary memory, or a file.
对于您的特定示例,TextWriter 是一个抽象类,它按顺序将字符写入流。它有几个实现(StreamWriter、StringWriter)在不同的上下文中很有用。您将使用当时有意义的任何一种。然而,对于几个 API,所需要的只是一个 TextWriter,或者可以调用“Write”或“WriteLine”的东西。如果您的编写器用于将内容放入字符串、某个任意内存或文件中,则这些 API 并不关心。
回答by Instance Hunter
I've always found the best thing to do is just look at what methods they provide and how you can build them. This is almost always the main, if not only, thing I care about when using an API. How do I build it and what can it do?
我一直发现最好的办法就是看看它们提供了什么方法以及如何构建它们。这几乎总是我在使用 API 时关心的主要问题(如果不是唯一的话)。我如何构建它以及它可以做什么?
You can't instantiate a TextWriter. It's abstract. That tells me the only real purpose it serves is, well, abstraction. If you write a function that takes any kind of writer as an argument, there's a good chance you should just take TextWriter to be more versatile.
您不能实例化 TextWriter。它是抽象的。这告诉我它服务的唯一真正目的是抽象。如果您编写的函数以任何类型的 writer 作为参数,则很有可能您应该只使用 TextWriter 以使其更加通用。
A StreamWriter you can instantiate, and it does just what it says, it writes to streams. That means it will need a stream to get any real writing done. Once you have that stream though, you can do all sorts of neat things like writing a whole line at once instead of having to deal with individual characters (or rather bytes) like you would directly on the stream.
一个 StreamWriter 您可以实例化,它按照它所说的做,它写入流。这意味着它需要一个流来完成任何真正的写作。但是,一旦您拥有该流,您就可以做各种整洁的事情,例如一次编写整行,而不必像直接在流上那样处理单个字符(或更确切地说是字节)。
So basically, you get a stream so you can feed it to a StreamWriter (or Reader). If you're writing text, you probably don't want to work directly with a stream, no more than you want to work with a character array instead of a string.
所以基本上,你会得到一个流,这样你就可以将它提供给 StreamWriter(或 Reader)。如果您正在编写文本,您可能不想直接使用流,就像您想使用字符数组而不是字符串一样。
FileStreams can conveniently be instantiated directly from the File and FileInfo classes, and in my usage, this is how they're usually instantiated. Get a file (I like to use FileInfo) and call OpenWrite(). Pass it along to a StreamWriter (which is just a type of TextWriter) and you're on your way.
FileStreams 可以方便地直接从 File 和 FileInfo 类实例化,在我的使用中,这就是它们通常的实例化方式。获取一个文件(我喜欢使用 FileInfo)并调用 OpenWrite()。将它传递给一个 StreamWriter(它只是一种 TextWriter),你就在路上了。
To generalize: When you want to figure out a class, try looking at how you instantiate it and what it can do. This usually clears up a lot.
概括地说:当您想弄清楚一个类时,请尝试查看如何实例化它以及它可以做什么。这通常会清除很多。
回答by Mani Gandham
Stream
is an abstract base class that represents a series of bytes.
Stream
是一个抽象基类,表示一系列字节。
MemoryStream
is a stream of bytes held in memory, backed by an Array.FileStream
is a stream of bytes in a file, usually backed by a file handle somewhere on disk.
MemoryStream
是保存在内存中的字节流,由数组支持。FileStream
是文件中的字节流,通常由磁盘上某处的文件句柄支持。
Text characters are themselves composed of bytes, and a single character can be multiple bytes, depending on the encoding. There are some standard classes that read and write text to different sources using a specific encoding.
文本字符本身由字节组成,单个字符可以是多个字节,具体取决于编码。有一些标准类使用特定的编码将文本读取和写入不同的源。
TextWriter
is an abstract base class for writing text characters to a destination.
TextWriter
是用于将文本字符写入目的地的抽象基类。
StreamWriter
writes text characters (converted to bytes) to a stream of bytes.StringWriter
writes text characters to a string (via a StringBuilder).
StreamWriter
将文本字符(转换为字节)写入字节流。StringWriter
将文本字符写入字符串(通过 StringBuilder)。
TextReader
is an abstract base class for reading text characters from a source.
TextReader
是用于从源读取文本字符的抽象基类。
StreamReader
reads text characters (converted from bytes) from a stream of bytes.StringReader
reads text characters from a string.
StreamReader
从字节流中读取文本字符(从字节转换而来)。StringReader
从字符串中读取文本字符。
Stream
, TextWriter
, TextReader
are all abstract base classes so they are never used directly but through an implementation like the ones described above. However you will see the base classes in method definitions so that different implementations can be used, including your own custom ones if necessary. Abstract classes are similar to interfaces but can actually define the logic for methods, which can be reused without every implementation repeating the same basic code.
Stream
, TextWriter
,TextReader
都是抽象基类,因此它们从不直接使用,而是通过上述实现的实现。但是,您将在方法定义中看到基类,以便可以使用不同的实现,必要时包括您自己的自定义实现。抽象类类似于接口,但实际上可以定义方法的逻辑,可以重用,而无需每个实现都重复相同的基本代码。