![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TStreamReader | TStream | Проблема с чтением потока
4el0vek © (2009-11-20 11:54:00)Доброго времени суток.
Столкнулся с любопытной проблемой.
Читаю CSV файл, используя TFileStream + TStreamReader.
Не совсем обычно, но думаю код не настолько быдлокод и будет в основном понятно, что я делаю:
http://www.everfall.com/paste/id.php?ccgxc810srtw
В общем проблема в том, что при считывании строк - в некоторых местах пропадают буквы. Каким то мистическим образом.
CurStr := OutStreamReader.ReadLine;
Вот когда я дебаггером проверяю, в этой строке уже не хватает буквы. Не всегда, но из ~1500 в ~10 строках глюки. Что это вообще может быть? Кодировка вроде верно указана, может это глюки СтримРидера? Штука то вроде новая.
4el0vek (2009-11-21 18:12:00) [1]короче меня эта свистопляска задрала, и я тупо заменил TStreamReader на TStringList. Проблема решена.
зы. И почему я сразу не подумал???
4el0vek (2009-11-20 18:09:00) [2]
> Что любопытно глюки при чтении CSV файла пропали. Все нормально
> стало. А вот при чтении файла, выгруженного из программы
> - буквы пропадают.
ага. вру я. буквы перестают исчезать только при повторной загрузке файла.
4el0vek (2009-11-20 17:36:00) [3]
> Плохиш © (20.11.09 17:30) [11]
да куда уж проще.
сейчас вот чуток повозился. сделал изменения - убрал при создании ридера параметр DetectBOM. Что любопытно глюки при чтении CSV файла пропали. Все нормально стало. А вот при чтении файла, выгруженного из программы - буквы пропадают. Интересно вот что - когда СтримРидер пишет в поток в кодировке UTF8, он BOM туда пишет или нет?
И еще внес изменение - TMemoryStream заменил на TFileStream чтобы посмотреть, как читается файл. По ссылке видно.
http://www.everfall.com/paste/id.php?ccgxc810srtw
Так вот в файле out.txt - никакие буквы не пропали. Значит проблема именно в чтении из потока ридером.
Плохиш (2009-11-20 17:30:00) [4]
> Могу показать код.
Такой же замороченный? Не надо.
Рекомендую выкинуть этот весь "код" и сделать всё заново и просто.
4el0vek (2009-11-20 16:55:00) [5]ну да, эт ясно. но опять же, глюки при чтении выгруженного файла возникают. а он пишется таки StreamWriter'ом. Могу показать код.
Медвежонок Пятачок (2009-11-20 16:46:00) [6]пишут строки.
а между строчками тоже кое-что пишут.
4el0vek (2009-11-20 16:39:00) [7]
> Медвежонок Пятачок © (20.11.09 16:17) [6]
это я понял. ладно, оцтавим в сторону CSV файл. тот же глюк происходит при чтении файла, выгруженного мной. Это по сути CSV файл, только зашифрованный. Пишется он стимрайтером. Как это объяснить?
И да, у меня не TReader/TWriter, а TStreamReader/TStreamWriter. Они появились толи в Д2007, толи в 2009-ой. И насколько я знаю пишут не двоичные таки данные, а вполне себе строки пишут. Щас справку гляну, для уверенности.
Медвежонок Пятачок (2009-11-20 16:35:00) [8]var mStream : TMemoryStream;
sr : TReader; sw : TWriter;
begin
mStream := nil; sr := nil; sw := nil;
mStream := TMemoryStream.Create;
sw := TWriter.Create(mStream,1024);
try
sw.WriteListBegin;
sw.WriteString('Мама');
sw.WriteString('мыла');
sw.WriteString('раму');
sw.WriteString('.');
sw.WriteString('Рама');
sw.WriteString('чистая.');
sw.WriteListEnd;
FreeAndNil(sw);
sr := TReader.Create(mStream,1024);
mStream.Position := 0;
sr.ReadListBegin;
while not sr.EndOfList do ShowMessage(sr.ReadString);
sr.ReadListEnd;
finally
if sr <> nil then sr.Free;
if sw <> nil then sw.Free;
if mStream <> nil then mStream.Free;
end;
Медвежонок Пятачок (2009-11-20 16:17:00) [9]еще раз.
стрим ридер умеет читать то, что записано стримрайтером.
стримрайтер пишет двоичные данные (маркеры разделителей полей и списков)
ксв файл не содержит такихразделителей.
посему прочитать его стримридером нельзя
4el0vek (2009-11-20 13:48:00) [10]
> Сергей М. © (20.11.09 13:16) [4]
неее.
я немного криво объясняю - есть такое. =)
постараюсь расписать подробно.
Выгрузка:
1. Создание потока TMemoryStream и "писателя" в поток TStreamWriter
2. Запись данных в поток.
3. Создание файлового потока TFileStream, режим fmCreate.
4. Шифрация потока MemoryStream. Она происходит так - в процедуре шифрации указывается сначала поток с данными, а затем поток, в который должны попасть зашифрованные данные. (Это набор компонентов DCP_Crypt). Ну и получается, что из потока в памяти данные попадают в файловый поток, только уже зашифрованные, ну и соответственно в файл.
Загрузка:
1. Создание файлового потока, режим fmOpenRead и "читателя" потока - TStreamReader. Чтение первой строки. Проверка первого слова - оно должно быть "parent".
2. Создание потока в памяти TMemoryStream и "писателя" в этот поток. Зачем это нужно - см. далее.
3. Если проверка пройдена, значит работа идет с обычным незашифрованным CSV файлом. В этом случае я читаю весь файловый поток, и эти данные пишу в поток в памяти. Попросту говоря содержимое файлового потока копирую в поток в памяти. Если же файл зашифрован, то я его расшифровываю. В результате расшифрованные данные все так же попадают в поток в памяти. С ним я и работаю дальше.
4. А работаю просто - "читателем" потока читаю построчно, и для каждой строки выполняю некие действия - разбор, создание объекта и т.д. Не в них суть. И вот на этой стадии у меня в считанной строке пропадает рандомная буква. Причем не всегда. Причем не с краю строки даже, а прям где то в середине.
Ну вот. Постарался изложить как можно более внятно. Прошу не ругать за (возможно) быдлокод и многобуквие =))
Сергей М. (2009-11-20 13:16:00) [11]
> 4el0vek (20.11.09 13:11) [3]
T.е. стримрайтер/ридер те нужен искл-но для шифрации/дешифрации потока, так что ли ?
4el0vek (2009-11-20 13:11:00) [12]ну как. там же почему код такой странный. задача стояла так - сделать выгрузку из БД в нечитаемый блокнотами и екселями файл =). и сделать загрузку из этого файла, НО, помимо этого надо загрузку из CSV сделать. ну и пошел по наиболее легкому пути (как мне показалось). При выгрузке пишу в поток СтримРайтером, затем поток шифрую и "записываю" в файл. При загрузке (см. код) - пробую первую строку на вкус. Если файл незашифрован, то просто копирую его в MemoryStream, если зашифрован, то расшифровываю.
А глюки имеются в обоих вариантах - и когда файл был выгружен из проги и зашифрован, и когда просто CSV взял. Пропадают буквы, мне прям странно так =)
Медвежонок Пятачок (2009-11-20 12:47:00) [13]стрим ридер предназначен для чтения того, чего записано стримрайтером.
ксв под это дело никак не подходит.
4el0vek (2009-11-20 12:03:00) [14]Прошу прощения, совсем забыл сказать, что
ОС: WinXP SP2
RAD Studio 2009