Книга: C# для профессионалов. Том II
Пример: ReadWriteText
Пример: ReadWriteText
Пример ReadWriteText
выводит результат использования классов StreamReader
и StreamWriter
. Он похож на предыдущий пример ReadBinaryFile
, но предполагает, что считываемый файл является текстовым файлом, и выводит его в этом виде. Он может сохранить файл (со всеми изменениями, которые будут сделаны в тексте в текстовом поле). Он будет сохранять любой файл в формате Unicode.
Снимок показывает использование ReadWriteText
для вывода того же файла CivNegotiations
, который использовался раньше. В этот раз, однако, мы сможем прочитать содержимое гораздо легче.
Не будем вдаваться в детали добавления методов обработки событий для диалога открытия файла, поскольку они по сути такие же, что и в примере BinaryFileReader
. Как и для данного примера, открытие нового файла приводит к вызову метода DisplayFile()
. Единственное реальное различие между этим примером и предыдущим состоит в реализации DisplayFile
, а также в том факте, что теперь имеется возможность сохранить файл. Она представлена другим пунктом меню — save. Обработчик для этого пункта вызывает другой добавленный в код метод — SaveFile()
. (Отметим, что этот файл всегда перезаписывает первоначальный файл, этот пример не имеет возможности записи в другой файл.)
Посмотрим сначала на SaveFile
, так как это простейшая функция. Мы просто записываем каждую строку текстового поля по очереди в поток StreamWriter
, полагаясь на метод StreamReader.WriteLine()
для добавления комбинации возврата каретки-перевода строки в конце каждой строки:
void SaveFile() {
является строковым полем основной формы, которое содержит имя прочитанного файла (как и в предыдущем примере). Отметим, что при открытии потока определяется кодирование Unicode. Если желательно записывать файлы в другом формате, необходимо изменить значение этого параметра. Второй параметр в этом конструкторе будет задан как true, если мы хотим добавлять к файлу, но в данном случае мы этого не делаем. Кодирование должно задаваться во время создания объекта записи потока. В дальнейшем оно доступно только для чтения как свойство
StreamWriter sw = new StreamWriter(ChosenFile, false, Encoding.Unicode);
foreach (string Line in textBoxContents.Lines) sw.WriteLine(Line);
sw.Close();
}
ChosenFileEncoding
.
Теперь проверим, как считываются файлы. Процесс чтения осложняется тем, что мы не знаем, пока не прочитаем файл, сколько строк он будет содержать (другими словами, сколько последовательностей (char)13 - (char)10
находится в файле). Решим эту проблему, считывая сначала файл в экземпляр класса StringCollection
, который находится в пространстве имен System.Collections.Specialized
. Этот класс создан для хранения множества строк, которые могут динамически увеличиваться. Он реализует два интересующих нас метода: Add()
, добавляющий строку в коллекцию, и CopyTo()
, который копирует коллекцию строк в обычный массив (экземпляр System.Array
). Каждый элемент объекта StringCollection
будет содержать одну строку файла.
Метод DisplayFile()
вызывает другой метод ReadFileIntoStringCollection()
, который реально считывает файл. После этого мы знаем, сколько имеется строк, поэтому можно скопировать StringCollection
в обычный массив фиксированного размера и передать этот массив в текстовое поле. Так как при создании копии копируются только ссылки на строки, а не сами строки, процесс будет достаточно эффективным:
void DisplayFile() {
StringCollection LinesCollection = ReadFileIntoStringCollection();
string [] LinesArray = new string[LinesCollection.Count];
LinesCollection.CopyTo(LinesArray, 0);
this.textBoxContents.Lines = LinesArray;
}
Второй параметр StringCollection.CopyTo()
указывает индекс в массиве назначения, где мы хотим начать размещение коллекции.
Теперь рассмотрим метод ReadFileIntoStringCollection()
. Мы используем StreamReader
для считывания каждой строки. Основной трудностью является необходимость подсчитывать считанные символы, чтобы не превысить емкость текстового поля:
ArrayList ReadFileIntoStringCollection() {
const int MaxBytes = 65536;
StreamReader sr = new StreamReader(ChosenFile);
StringCollection Result = new StringCollection();
int nBytesRead = 0;
string NextLine;
while ((NextLine = sr.ReadLine()) != null) {
nBytesRead += NextLine.Length;
if (nBytesRead > MaxBytes) break;
Result.Add(NextLine);
}
sr.Close();
return Result;
}
Код завершен.
Если выполнить ReadWriteText
— считать файл CivNegotiations
и затем сохранить его, то файл будет иметь формат Unicode. Это невозможно для любого из обычных оконных приложений: Notepad, Wordpad и даже наш собственный пример ReadWriteText
будут по-прежнему считывать файл и выводить его правильно в Windows NT/2000/XP, хотя, так как Windows 9х не поддерживает Unicode, приложения типа Notepad не смогут понять файл Unicode на этих платформах (Если загрузить пример с web-сайта издательства Wrox Press, то можно попробовать это сделать.) Однако, если попробовать вывести файл снова с помощью предыдущего примера ReadBinaryFile
, то разница будет заметна немедленно, как на следующем экране. Два начальных файла указывают, что файл имеет формат Unicode, и поэтому мы видим, что каждый символ представлен двумя байтами. Этот последний факт вполне очевиден, поскольку старший байт каждого символа в данном конкретном файле равен нулю, поэтому каждый второй байт в этом файле выводится теперь как x00:
- Пример установочного скрипта
- Пример из практики
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Примеры получения статистики
- Пример применения метода «пять почему»
- Пример 12-8. Частота встречаемости отдельных слов
- 1.2.5. Пример программы
- Пример 17-10. Блочный комментарий
- Примеры
- 2. Пример создания базового отношения в записи на псевдокоде
- Пример 9-8. Содержимое $* и $@, когда переменная $IFS -- пуста
- Часть I На примере денег