Текущий архив: 2011.07.03;
Скачать: CL | DM;
ВнизTStreamReader | TStream | Проблема с чтением потока Найти похожие ветки
← →
4el0vek (2009-11-20 11:54) [0]Доброго времени суток.
Столкнулся с любопытной проблемой.
Читаю CSV файл, используя TFileStream + TStreamReader.
Не совсем обычно, но думаю код не настолько быдлокод и будет в основном понятно, что я делаю:
http://www.everfall.com/paste/id.php?ccgxc810srtw
В общем проблема в том, что при считывании строк - в некоторых местах пропадают буквы. Каким то мистическим образом.CurStr := OutStreamReader.ReadLine;
Вот когда я дебаггером проверяю, в этой строке уже не хватает буквы. Не всегда, но из ~1500 в ~10 строках глюки. Что это вообще может быть? Кодировка вроде верно указана, может это глюки СтримРидера? Штука то вроде новая.
← →
4el0vek (2009-11-20 12:03) [1]Прошу прощения, совсем забыл сказать, что
ОС: WinXP SP2
RAD Studio 2009
← →
Медвежонок Пятачок © (2009-11-20 12:47) [2]стрим ридер предназначен для чтения того, чего записано стримрайтером.
ксв под это дело никак не подходит.
← →
4el0vek (2009-11-20 13:11) [3]ну как. там же почему код такой странный. задача стояла так - сделать выгрузку из БД в нечитаемый блокнотами и екселями файл =). и сделать загрузку из этого файла, НО, помимо этого надо загрузку из CSV сделать. ну и пошел по наиболее легкому пути (как мне показалось). При выгрузке пишу в поток СтримРайтером, затем поток шифрую и "записываю" в файл. При загрузке (см. код) - пробую первую строку на вкус. Если файл незашифрован, то просто копирую его в MemoryStream, если зашифрован, то расшифровываю.
А глюки имеются в обоих вариантах - и когда файл был выгружен из проги и зашифрован, и когда просто CSV взял. Пропадают буквы, мне прям странно так =)
← →
Сергей М. © (2009-11-20 13:16) [4]
> 4el0vek (20.11.09 13:11) [3]
T.е. стримрайтер/ридер те нужен искл-но для шифрации/дешифрации потока, так что ли ?
← →
4el0vek (2009-11-20 13:48) [5]
> Сергей М. © (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 16:17) [6]еще раз.
стрим ридер умеет читать то, что записано стримрайтером.
стримрайтер пишет двоичные данные (маркеры разделителей полей и списков)
ксв файл не содержит таких разделителей.
посему прочитать его стримридером нельзя
← →
Медвежонок Пятачок © (2009-11-20 16:35) [7]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;
← →
4el0vek (2009-11-20 16:39) [8]
> Медвежонок Пятачок © (20.11.09 16:17) [6]
это я понял. ладно, оцтавим в сторону CSV файл. тот же глюк происходит при чтении файла, выгруженного мной. Это по сути CSV файл, только зашифрованный. Пишется он стимрайтером. Как это объяснить?
И да, у меня не TReader/TWriter, а TStreamReader/TStreamWriter. Они появились толи в Д2007, толи в 2009-ой. И насколько я знаю пишут не двоичные таки данные, а вполне себе строки пишут. Щас справку гляну, для уверенности.
← →
Медвежонок Пятачок © (2009-11-20 16:46) [9]пишут строки.
а между строчками тоже кое-что пишут.
← →
4el0vek (2009-11-20 16:55) [10]ну да, эт ясно. но опять же, глюки при чтении выгруженного файла возникают. а он пишется таки StreamWriter"ом. Могу показать код.
← →
Плохиш © (2009-11-20 17:30) [11]
> Могу показать код.
Такой же замороченный? Не надо.
Рекомендую выкинуть этот весь "код" и сделать всё заново и просто.
← →
4el0vek (2009-11-20 17:36) [12]
> Плохиш © (20.11.09 17:30) [11]
да куда уж проще.
сейчас вот чуток повозился. сделал изменения - убрал при создании ридера параметр DetectBOM. Что любопытно глюки при чтении CSV файла пропали. Все нормально стало. А вот при чтении файла, выгруженного из программы - буквы пропадают. Интересно вот что - когда СтримРидер пишет в поток в кодировке UTF8, он BOM туда пишет или нет?
И еще внес изменение - TMemoryStream заменил на TFileStream чтобы посмотреть, как читается файл. По ссылке видно.
http://www.everfall.com/paste/id.php?ccgxc810srtw
Так вот в файле out.txt - никакие буквы не пропали. Значит проблема именно в чтении из потока ридером.
← →
4el0vek (2009-11-20 18:09) [13]
> Что любопытно глюки при чтении CSV файла пропали. Все нормально
> стало. А вот при чтении файла, выгруженного из программы
> - буквы пропадают.
ага. вру я. буквы перестают исчезать только при повторной загрузке файла.
← →
4el0vek (2009-11-21 18:12) [14]короче меня эта свистопляска задрала, и я тупо заменил TStreamReader на TStringList. Проблема решена.
зы. И почему я сразу не подумал???
Страницы: 1 вся ветка
Текущий архив: 2011.07.03;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.003 c