forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   С# (http://forum.boolean.name/forumdisplay.php?f=128)
-   -   StreamReader Position (http://forum.boolean.name/showthread.php?t=18313)

seaman 04.07.2013 20:51

StreamReader Position
 
Читаю построково тестовый файл. В файле данные в произвольном порядке. Т.е. чтобы не пропустить нужно каждую порцию искать с начала файла. Методы чтения строки (ReadLine) есть в StreamReader и StringReader (больше не нашел). Вернуться в начало файла принципиально можно в StreamReader.
Инициализирую его из файла. Пытаюсь изменить позицию.
Код:

StreamReader sr = new StreamReader(file);
sr.BaseStream.Seek(0, SeekOrigin.Begin)

В дебаге вижу, что sr.BaseStreamPosition изменился, но читает все равно не в начале файла, а там где было предыдущее чтение. Нашел, что StreamReader использует внутренний буфер, хоть это и не BufferedStream, и для того чтобы изменение позиции сработало нужно вызваеть DiscardBufferedData. Однако "Этот метод отрицательно влияет на быстродействие". Т.е. скорее всего производится повторное чтение файла с диска в буфер. Лажа. С тем же успехом можно просто повторно открывать поток.
Можно, конечно, сначала считать файл в свой буфер, типа:
Код:

FileStream fs = new FileStream(file, FileMode.Open);
byte[] buf = new byte[fs.Length];
fs.Read(buf, 0, fs.Length);

Затем из этого буфера создать MemoryStream:
Код:

MemoryStream ms = new MemoryStream(buf);
И уже из него при необходимости считывать с начала файла каждый раз создавать StreamReader. Ну или в данном случае можно сбрасывать буфер, т.к. тут не будет повторной загрузки с диска - просто заполнение буфера из MemoryStream.
Однако это все же как -то неправильно.

Вопрос. Я что-то не знаю, не понимаю и можно проще реализовать многократное чтение с начала файла без повторной загрузки его с диска. Или все же можно только через ж...

Dream 04.07.2013 21:01

Ответ: StreamReader Position
 
Ну а почему не копировать в буфер. если не ошибаюсь там указывается индекс с какого начинать и длинна, и копируй сколько хочешь и где хочешь. тоесть сразу из StreamReader делать fs.Read(buf, 0, fs.Length); когда надо и никаких дублирований же

seaman 04.07.2013 21:51

Ответ: StreamReader Position
 
Не понял. Что копировать?
Вероятно я плохо объяснил.
Задача.
Прочитать построчно часть текстового файла. Именно построчно - строка за строкой. Ее (эту часть) нужно найти сначала, т.к. она может быть не с начала файла. Что-то с прочитанным сделать.
Затем прочитать так же другую часть. Эта другая часть неизвестно где - возможно до предыдущей прочитанной части. Ее (эту вторую часть) тоже нужно найти сначала. Т.е. нужно по новой с начала начать читать файл. Построчно.
Я сейчас делаю так:
Код:

byte[] buf;
using (FileStream fs = new FileStream("file.txt", FileMode.Open))
{
    buf = new byte[fs.Length];
    fs.Read(buf, 0, (int)fs.Length);
}

using (MemoryStream ms = new MemoryStream(buf))
{
    using (StreamReader sr = new StreamReader("ms"))
    {
          foreach (string data in dataArray)
          {
              sr.BaseStream.Seek(0, SeekOrigin.Begin);
              sr.DiscardBufferedData();
              _dataes.Add(data, new Data(sr, data));
          }
    }
}

В конструкторе Data ищу нужный кусок по имени (data) и читаю/парсю его во внутренние переменные класса Data.
Т.е. сначала читаю весь файл в буфер, затем из буфера делаю StreamReader и уже его использую.

Мне это не нравится. Есть ли способ нормаль менять позицию чтения в StreamReader, не сбрасывая его внутренний буфер? Или может есть способ читать из потока (MemoryStream/FileStream) по строкам (как это делает StreamReader) не городя огород со своим разбором Encoding и т.п.

Dream 05.07.2013 13:54

Ответ: StreamReader Position
 
не сталкивался с такой потребностью. скопи руй весь поток в string и оттуда читай как угодно в любом порядке и направлении

seaman 05.07.2013 15:04

Ответ: StreamReader Position
 
Чем читать из string построчно? Можно, конечно, разбить строку Split-ом по Environment.NewLine.
ЗЫ: пока я думаю над алгоритмом. Отсутствие необходимости в подобном у других говорит о том, что что-то не так с алгоритмом. Скорее всего сменю алгоритм и у меня потребность повторного чтения с начала файла отпадет.

Dream 05.07.2013 20:07

Ответ: StreamReader Position
 
ну в влюбом случае ты в конечном итого конвертишь в string каждую линию. так что будет проще сразу считать весь файл в string, рабить на линии и уже с ними работать. ну и не совсем понятно что в конечном итого ты хочешь получить от такого. если парсишь результат каждой строчки в какойто тип то может проще сразу рпспарсить весь файл( или кешировать потом распарсиное) и так уже работать


Часовой пояс GMT +4, время: 10:36.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot