Когда для записи файла следует использовать объект filestream вместо объекта streamwriter
What functionality is allowed via StreamReader and StreamWriter when working with files which can't be done via FileStream , or vice versa? I checked the docs and they both have read / write options, including more advanced ones. So when should I use each of those?
StreamReader and StreamWriter can use FileStream internally, depending on how you construct them. The difference is that the specialised classes are for dealing with only text files.
2 Answers 2
A FileStream is a Stream. Like all Streams it only deals with byte[] data.
A StreamWriter : TextWriter, is a Stream-decorator. A TextWriter encodes Text data like string or char to byte[] and then writes it to the linked Stream.
You use a bare FileStream when you have byte[] data. You add a StreamWriter when you want to write text. Use a Formatter or a Serializer to write more complex data.
FileStream is the lowest-level Stream object for working with local files. It therefore works with files as binary (bytes). You can read so many bytes, or write so many bytes.
When it comes to working with text, we have to factor in text encoding. There are many text encodings created for different cultures with different character sets. A common one these days is UTF8 (a form of unicode). Text encoding is the way we tell the computer to represent text as bytes. Using UTF8, the letter "A" would be represented by a single byte, but the Japanese hiragana "あ" would be 3 bytes. Encoding allows us to read and write text correctly. You can read more about that here (in case the link ever breaks: WaybackMachine link).
StreamReader and StreamWriter are built around reading text, so they handle the encoding for us. One is for reading, and the other is for writing. If you instantiate StreamReader or StreamWriter using the constructor that accepts a filename, it will actually use FileStream internally.
StreamReader gives us methods such as:
-
- Which reads from the file until carriage return + newline ( \r\n ) or just newline ( \n ) is found, indicating the end of a single line of text, and returns a string . - Which reads the entire file contents into a string .
StreamWriter gives us methods such as:
-
- Which can write as little as a single character, or an entire string to the file, but without terminating the line. which will do the same as Write , but it will also end the line so any subsequent writes go to the next line in the file.
In contrast, FileStream only has methods like Read and Write , which work with bytes.
однако вышеизложенное добавляет новую строку вместо перезаписи файла новыми изменениями. Это необходимо сделать, чтобы никакое другое приложение не могло получить доступ к файлу между чтением записи, поэтому я создаю reader и writer из объекта FileStream.
Я знаю, что вы можете создать StreanWriter со вторым параметром, установленным в false, как описано здесь. Однако, когда создание StreamWriter, как указано выше, не является одним из параметров.
проблема заключается в том, что чтение из потока переходит в конец файла. Далее записи будут добавляться.
это приведет к полной перезаписи.
зачем использовать SetLength ? Ваш новый контент может быть короче существующей строки! Последнее, что вам нужно, это старый контент в конце вашего файла.
здесь вам нужно сделать несколько шагов, но позвольте мне сделать мои предположения ясными:
вы должны держать файл открытым и заблокированным в течение всей операции, чтобы предотвратить другие от доступа к файлу в течение этого времени.
С этим сказано, вот что вам нужно сделать:
- вам нужно прочитать содержимое с помощью StreamReader , Как вы сделали
- вам нужно переместить базовый поток обратно в начало, его положение было изменено чтением через читателя
- вам нужно записать преобразованное содержимое через StreamWriter , Как вы сделали
- вам нужно смыть писателя из-за следующего шага
- вам нужно усечь базовый поток / файл до его текущей позиции, чтобы обработать преобразование, которое сокращает содержимое.
код для всего этого может выглядеть так помощью linqpad программа:
то, что вы можете сделать, - это переместить потоки, а также удалить буферизованные данные, чтобы убедиться, что ничто не мешает. Возьмем Ваш пример:
если новые данные меньше, чем старые, вам нужно будет усечь оставшиеся данные. Используя sw.SetLength(newString.Length); .
вы можете избежать эти низкоуровневые Stream и их Reader / Writer С помощью в LINQ:
позвольте мне сначала извиниться, если этот вопрос может показаться, возможно, дилетантским для опытных программистов среди вас, дело в том, что у меня было много аргументов об этом на работе, поэтому я действительно хочу получить это прямо, и именно поэтому я полагаюсь на сообщество stackoverflow, чтобы решить это раз и навсегда :)
Итак, с одной стороны, согласно MSDN, у нас есть:
Класс TextWriter
представляет писатель, который может написать последовательный ряд символов. Этот класс является абстрактным.
Класс FileStream
предоставляет Stream в файл, поддерживая синхронные и асинхронное чтение и запись оперативный.
Класс StreamWriter
реализует TextWriter для написания символов в поток в определенной кодирование.
с другой стороны, это очевидно все они принадлежат системе.Но, учитывая, что примеры MSDN смешивают некоторые из них, я все еще не достигаю желаемого момента A-ha.
любой комментарий будет более чем оценен, спасибо заранее!
потоки ручка байт писатели ручки символы.
байт != письмена. Символ может представлять более одного байта. Отображение символов в байты называется кодирование.
A FileStream относится к байт записывается в файл, подобно тому, как MemoryStream относится к байтам, записанным в буфер в памяти. Чтобы записать символы в поток, вам нужно будет преобразовать их в строку байтов. Вот где StreamWriter вступает в игру. Он принимает последовательность символов и кодировку и превращает ее в последовательность байтов.
A TextWriter - это интерфейс (ну, абстрактный базовый класс), которого должны придерживаться все авторы. Он имеет все операции, основанные на символах. Эквивалентом для байтов является Stream абстрактный базовый класс.
вещи также идут в противоположном направлении. Есть TextReader абстрактный базовый класс, описывающий, как читать символы откуда-то и А StreamReader , что позволяет читать символы из байт-ориентированного потока, поставляющего кодировку, но на этот раз используется в обратном порядке, чтобы агрегировать любые многобайтовые последовательности в отдельные символы, где это уместно.
A Stream может использоваться как для чтения, так и для записи, поскольку байты являются элементами самого низкого уровня, используемыми в операциях ввода-вывода.
Я всегда считал, что лучше всего просто посмотреть, какие методы они предоставляют и как вы можете их построить. Это почти всегда главная, если не единственная, вещь, о которой я забочусь при использовании API. Как его построить и что он может сделать?
вы не можете создать экземпляр TextWriter. Это абстракция. Это говорит мне, что единственная реальная цель, которой он служит, это, ну, абстракция. Если вы пишете функцию, которая принимает любой писатель в качестве аргумента, есть хороший шанс, что вы должны просто взять TextWriter быть более универсальным.
StreamWriter вы можете создать экземпляр, и он делает только то, что он говорит, он записывает в потоки. Это означает, что ему понадобится поток, чтобы получить любую реальную запись. Как только у вас есть этот поток, вы можете делать всевозможные аккуратные вещи, такие как писать целую строку сразу, а не иметь дело с отдельными символами (или, скорее, байтами), как вы бы прямо в потоке.
таким образом, в основном, вы получаете поток, чтобы вы могли кормить его Модулю записи StreamWriter (или читателя). Если вы пишете текст, вы, вероятно, не хотите работать непосредственно с потоком, не больше, чем вы хотите работать с массивом символов вместо строки.
FileStreams можно удобно создавать непосредственно из классов File и FileInfo, и в моем использовании они обычно создаются именно так. Получите файл (мне нравится использовать FileInfo) и вызовите OpenWrite (). Передайте его StreamWriter (который является просто типом TextWriter) , и вы на своем путь.
чтобы обобщить: когда вы хотите выяснить класс, попробуйте посмотреть, как вы создаете его экземпляр и что он может сделать. Обычно это многое проясняет.
существует очевидная разница между" потоком "и"писателем/читателем".
поток-это представление уровня байта и действительно абстрактная концепция, которая может быть реализована различными способами. Например, у вас есть FileStream и MemoryStream. Оба они являются потоками байтов, но они хранятся по-разному.
для вашего конкретного примеры, TextWriter-это абстрактный класс, который последовательно записывает символы в поток. Он имеет несколько реализаций (StreamWriter, StringWriter), которые полезны в разных контекстах. Вы бы использовали то, что имеет смысл в то время. Однако для нескольких API все, что требуется, - это TextWriter или что-то, что можно назвать "Write" или "WriteLine". Это не касается этих API, если ваш писатель используется для ввода материала в строку, произвольную память или файл.
на FileStream class управляет получением дескриптора файла и открытием его для чтения или записи и других функций файловой системы. BinaryWriter записывает двоичные данные в поток и модулю записи StreamWriter записывает символьные данные в поток. Они оба могут использовать объект FileStream для записи двоичных или символьных данных в файлах.
TextWriter-это базовый класс, от которого наследуется StreamWriter. А TextWriter предназначен для взять тип и выведите строку, используя ее написать метод. Реализация StreamWriter в TextWriter.Метод Write записывает строку или символьные данные в поток. BinaryWriter не наследует TextWriter, поскольку он не записывает символьные данные в поток.
Stream - абстрактный базовый класс, представляющий ряд байтов.
MemoryStream - это поток байтов, хранящихся в памяти, поддерживаемый массивом.
FileStream - это поток байтов в файле, обычно поддерживаемый дескриптором файла где-то на диске.
текстовые символы сами состоят из байтов, и один символ может быть несколько байтов, в зависимости от кодировки. Есть некоторые основные классы, которые читают и пишут текст в разные источники с заданной кодировкой.
TextWriter - абстрактный базовый класс для записи текстовых символов в пункт назначения.
- StreamWriter записывает текстовые символы (преобразованные в байты) в поток байтов.
- StringWriter записывает текстовые символы в строку (через StringBuilder).
TextReader является абстрактным базовым классом для чтения текстовых символов из источник.
- StreamReader считывает текстовые символы (преобразованные из байтов) из потока байтов.
- StringReader считывает текстовые символы из строки.
Stream , TextWriter , TextReader все абстрактные базовые классы, так как они никогда не используются напрямую, а через реализацию, как описано выше. Однако вы увидите базовые классы в определениях методов, чтобы можно было использовать различные реализации, включая ваши собственные заказ при необходимости. Абстрактные классы похожи на интерфейсы, но могут фактически определять логику для методов, которые могут быть повторно использованы без повторения одной и той же базовой реализации.
чем отличается FileStream от StreamWriter в dotnet?
какой контекст вы должны использовать? В чем их преимущество и недостаток?
можно ли объединить эти два в один?
чем отличается FileStream от StreamWriter в dotnet?
A FileStream Это Stream . Как и все потоки, он имеет дело только с byte[] данные.
A StreamWriter : TextWriter , является поток-декоратор. TextWriter кодирует текстовые данные, такие как string или char в byte[] а затем записывает его в связанный Stream .
какой контекст вы должны использовать? В чем их преимущество и недостаток?
вы используете голый FileStream, когда у вас есть byte[] данные. Добавить StreamWriter если вы хотите написать текст. Используйте форматер или сериализатор для записи более сложных данных.
можно ли объединить эти два в один?
да. Вам всегда нужен поток для создания StreamWriter. Вспомогательный метод System.IO.File.CreateText("path") создаст их в комбинации, а затем вам нужно будет только Dispose () внешний писатель.
FileStream пишет байты, StreamWriter пишет текст. Вот и все.
FileStream явно предназначен для рабочих файлов.
StreamWriter может использоваться для потока в любой тип поток - сетевые сокеты, файлы и т. д.
предоставляет Stream в файл, поддерживающий синхронные и асинхронные операции чтения и записи.
реализует textwriter для записи символов в поток в определенной кодировке.
самая очевидная разница в том, что FileStream позволяет осуществлять операции чтения/записи, в то время как StreamWriter это пишут только.
на StreamWriter страница продолжает добавлять:
StreamWriter предназначен для вывода символов в определенной кодировке, тогда как классы, производные от Stream, предназначены для ввода и вывода байтов.
Итак, вторая разница в том, что FileStream для байтов, в то время как StreamWriter для текста.
Это два разных уровня, используемых для вывода информации в известные источники данных.
FileStream - это тип потока, который концептуально является механизмом, указывающим на некоторое местоположение и может обрабатывать входящие и/или исходящие данные В и из этого местоположения. Существуют потоки для чтения / записи в файлы, сетевые подключения, память, каналы, консоль, прослушиватели отладки и трассировки и несколько других типов источников данных. В частности, FileStream существует для выполнения чтения и запись в файловую систему. Большинство потоков довольно низкоуровневые в своем использовании и имеют дело с данными в виде байтов.
StreamWriter-это оболочка для потока, которая упрощает использование этого потока для вывода простого текста. Он предоставляет методы, которые принимают строки вместо байтов, и выполняет необходимые преобразования в и из байтовых массивов. Есть и другие авторы; другой основной, который вы бы использовали, - XmlTextWriter, который облегчает запись данных в формате XML. Есть также читатель аналоги авторы, которые аналогичным образом обернуть поток и облегчить получение данных обратно.
одно ключевое отличие (в дополнение к приведенным выше комментариям) может заключаться в том, что FileStream поддерживает случайное чтение и запись на диск в любой указанный FileStream.Позиция. Для больших модификаций файлов это может быть бесценно.
What context are you supposed to use it? What is their advantage and disadvantage?
Is it possible to combine these two into one?
6 Answers 6
What is different between FileStream and StreamWriter in dotnet?
A FileStream is a Stream . Like all Streams it only deals with byte[] data.
A StreamWriter : TextWriter is a Stream-decorator. A TextWriter encodes the primitive type like string, int and char to byte[] and then writes hat to the linked Stream.
What context are you supposed to use it? What is their advantage and disadvantage?
You use a bare FileStream when you have byte[] data. You add a StreamWriter when you want to write text. Use a Formatter or a Serializer to write more complex data.
Is it possible to combine these two into one?
Yes. You always need a Stream to create a StreamWriter. The helper method System.IO.File.CreateText("path") will create them in combination and then you only have to Dispose() the outer writer.
Also is important to note that FileStream is a type of stream, that is specifically tailored towards files. Streams natively work with bytes, however StreamWriter / Reader will write / read text on any stream, not just FileStream s. For example, MemoryStreams , NetworkStreams , etc..
FileStream writes bytes, StreamWriter writes text. That's all.
A FileStream is explicitly intended for working files.
A StreamWriter can be used to stream to any type of Stream - network sockets, files, etc.
Excellent reference for streams, although it does not cover random access R/W streams. Especially the serialization/deserialization information and the demonstration of non-file streams are very useful. +1
They are two different levels used in outputting information to known data sources.
A FileStream is a type of Stream, which is conceptually a mechanism that points to some location and can handle incoming and/or outgoing data to and from that location. Streams exist for reading/writing to files, network connections, memory, pipes, the console, debug and trace listeners, and a few other types of data sources. Specifically, a FileStream exists to perform reads and writes to the file system. Most streams are pretty low-level in their usage, and deal with data as bytes.
A StreamWriter is a wrapper for a Stream that simplifies using that stream to output plain text. It exposes methods that take strings instead of bytes, and performs the necessary conversions to and from byte arrays. There are other Writers; the other main one you'd use is the XmlTextWriter , which facilitates writing data in XML format. There are also Reader counterparts to the Writers that similarly wrap a Stream and facilitate getting the data back out.
Well, from the MSDN for FileStream :
Exposes a Stream around a file, supporting both synchronous and asynchronous read and write operations.
Implements a TextWriter for writing characters to a stream in a particular encoding.
The most obvious difference is that FileStream allows read/write operations, while StreamWriter is write only.
The StreamWriter page goes on to add:
StreamWriter is designed for character output in a particular encoding, whereas classes derived from Stream are designed for byte input and output.
So a second difference is that FileStream is for bytes, while StreamWriter is for text.
Читайте также: