Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Delphi > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 21.06.2018, 10:48   #1
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 168
Репутация: 39
По умолчанию TStreamReader и метод ReadBlock

Ув. форумчане, направьте в нужную сторону. Проблема вроде и есть, и вроде ее нет. Но хочется разобраться.
Собрал свой XML парсер, все работает замечательно для XML оч. больших объемов. Но во всем этом мёде, есть ложечка.......
При загрузке одного файла никаких сбоев не наблюдаю, но при цикличном Load двух и более файлов
в этом месте:
Код:

  SetLength(FChildBlock,FSizeBlock);
  ReadBlock(FChildBlock,0,FSizeBlock);

наблюдаю потерю "чаров" при размере блока 100 000, при размере 10 000 потерь нет. Вот чилд XML:
Код:

<ZAP N_ZAP="1129">
<PACIENT DR="1982-08-24"/>
<SLUCH DATE_1="2017-02-16" DS1="E03" LPU="720037" RSLT="314" GOSP_TYPE="3" PVT="0" AP_TYPE="П"/>
<EKMP NO_PROBLEM="1" TYPE="0"/>
</ZAP>

А это я получаю в FChildBlock:
Код:

<ZAP N_ZAP="1129">
<PACIENT DR="1982-08-24"/>
<SLUCH DATE_1="2017-02"  -<---- ХДЕ ОСТАЛЬНОЕ? оО/>
<EKMP NO_PROBLEM="1" TYPE="0"/>
</ZAP>

......естественно символов больше, но пример для понимания аказии.
Код перепроверил, все очищаю и уничтожаю. Загрузка XML прописана следующим образом:

Код:

for I := 0 to FFileBox.Count - 1 do
  begin
    FXmlReads := TXmlReader.Create(FFileBox[i],TEncoding.Default);
    FXmlReads.BaseStream.Position := 0;
    FXmlReads.DiscardBufferedData;
    while FXmlReads.LastChild = False do
    begin
      Inc(HH);
      Application.ProcessMessages;
      FXmlReads.WriteChild('ZAP',ReadSize);
      if HH mod 1000 = 0  then
      begin
        LabelInfo.Caption := (' - Чтение файла ' + IntToStr(I + 1) + ' из ' + IntToStr(FFileBox.Count) + '. Выполнено: ' + FormatFloat('0',(FXmlReads.Position / FXmlReads.BaseStream.Size) * 100) + ' %');
        LabelInfo.Refresh;
      end;
    end;
  FXmlReads.CloseFile;
  FreeAndNil(FXmlReads);
  end;

P/S: TXmlReader = class (TStreamReader)
ReadSize := 100 000, при 10 000 все ОК
__________________
Пишу много и развернуто

Последний раз редактировалось Heneken87; 21.06.2018 в 10:58.
Heneken87 вне форума   Ответить с цитированием
Старый 21.06.2018, 11:33   #2
Serge_Bliznykov
МегаМодератор
СуперМодератор
 
Регистрация: 09.01.2008
Сообщений: 23,904
Репутация: 5228
По умолчанию

во-первых, Вы код, где идёт чтение и работа с FChildBlock не выложили.
к чему выложенный кусок кода - мне непонятно.

а во-вторых,
Цитата:
Сообщение от Heneken87 Посмотреть сообщение
А это я получаю в FChildBlock:
это какая-то нереальная фантастика.
не может пропасть часть символов внутри. может пропасть в начале, может — в конце. Но не внутри!

Скажите, после того, как Вы прочитали в FChildBlock Вы выполняете процедуру парсинга? Очень вероятно, что это именно она косячит.
Serge_Bliznykov вне форума   Ответить с цитированием
Старый 21.06.2018, 12:33   #3
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 168
Репутация: 39
По умолчанию

Спасибо за быстрый ответ.
Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
во-первых, Вы код, где идёт чтение и работа с FChildBlock не выложили.
Не вложил, чтобы не городить код. Причина могла быть в чем то другом.


Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Скажите, после того, как Вы прочитали в FChildBlock Вы выполняете процедуру парсинга? Очень вероятно, что это именно она косячит.
не исключено. Я пока не могу найти в чем дефект. Когда чтение из одного файла, этой проблемы нет.
Код:

 .......
  SetLength(FChildBlock,FSizeBlock);
  ReadBlock(FChildBlock,0,FSizeBlock);
  TextAll := (PChar(FChildBlock));
  StartC :=  Pos('<' + ChildName + ' ',TextAll);
  EndC :=  Pos('</' + ChildName + '>',TextAll);
  if (StartC = 0) and (EndC = 0) then
  LastChild := True
  else  LastChild := False;
  if (StartC <> 0) and (EndC = 0) then
  begin
    ShowMessage('В загружаемом блоке не найден конец элемента ' + ChildName + ' попробуйте увеличить блок чтения');
    LastChild := True;
    Exit;
  end;
  while (EndC <> 0) and (StartC <> 0)  do
  begin
    TextBlock := Copy(TextAll,StartC, EndC - StartC + Length(ChildName) + 3);
    Insert(TChild.Create(ChildName,TextBlock,Self),FChilds,GetCountChild);
    TextAll := Copy(TextAll,EndC + Length(ChildName) + 3,Length(TextAll));
    LastPosition := LastPosition + EndC + Length(ChildName) + 2;  <---- Это возникает скорее всего тут. Неясно только почему это только при работе с множеством файлов. 
    StartC := 0;
    EndC := 0;
    StartC :=  Pos('<' + ChildName + ' ',TextAll);
    EndC :=  Pos('</' + ChildName + '>',TextAll);
    if (StartC <> 0) and (EndC = 0) then
    begin
      LastPosition := LastPosition + StartC - 1;
      Break;
    end;
  end;

__________________
Пишу много и развернуто
Heneken87 вне форума   Ответить с цитированием
Старый 21.06.2018, 12:38   #4
Serge_Bliznykov
МегаМодератор
СуперМодератор
 
Регистрация: 09.01.2008
Сообщений: 23,904
Репутация: 5228
По умолчанию

LastPosition обнулять не забываете?

а так - раз ситуация повторяется, тогда моделируйте ситуацию, когда возникает глюк, ставьте точку останова и смотрите в отладчике, что не так.
вариантов много. например, Вы используете переменные типа byte, word или smallint для позиций.
а может в логике есть небольшой изъян. Без отладчика и понимания алгоритма - трудно сразу сказать.

Последний раз редактировалось Serge_Bliznykov; 21.06.2018 в 12:40.
Serge_Bliznykov вне форума   Ответить с цитированием
Старый 21.06.2018, 12:49   #5
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 168
Репутация: 39
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
LastPosition обнулять не забываете?
нет конечно не забываю) Чтение файла:
1- Создал класс TXmlReader
2- Установил дефолты
3- Пропарсил
4- Закрыл файл
5 - Уничтожил класс

стоит эти пункты в цикл завернуть..приехали.
Если честно там и с отладчиком не просто=) Методы рекурсивные, XML любой вложенности кушает. На простых XML я не могу отловить такую ошибку,а на сложных может крыша съехать))) Использую Int64 для позиций. Через отладчик, как раз и нашел что в
Код:

  SetLength(FChildBlock,FSizeBlock);
  ReadBlock(FChildBlock,0,FSizeBlock);
  TextAll := (PChar(FChildBlock));

TextAll получаю кастрированый текст (( А золдея с ножичком не видать))
LastPosition это TStremReader.Position, хотя вы поняли что это и зачем это
__________________
Пишу много и развернуто

Последний раз редактировалось Heneken87; 21.06.2018 в 12:52.
Heneken87 вне форума   Ответить с цитированием
Старый 21.06.2018, 12:56   #6
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 168
Репутация: 39
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Без отладчика и понимания алгоритма - трудно сразу сказать.
По алгоритму, чей листинг выложен. Метод ищет в переданном тексте начало и конец требуемого чилдика. Нашел, вырезал весь чилдик, перешел к следующему и так пока не вырежет все блоки. .... МБ проблема в переносе строки может крыться..... если да, тогда я вообще не понимаю как это зависит от кол-ва файлов...
__________________
Пишу много и развернуто
Heneken87 вне форума   Ответить с цитированием
Старый 21.06.2018, 21:36   #7
Slym
Профессионал
 
Регистрация: 07.12.2011
Адрес: Siberia
Сообщений: 1,008
Репутация: 698
По умолчанию

ReadBlock- функция
SetLength(FChildBlock,FSizeBlock);
TextAll :=string.Create(FChildBlock,0,ReadB lock(FChildBlock,FSizeBlock))
__________________
Не стесняемся, плюсуем!
Slym вне форума   Ответить с цитированием
Старый 22.06.2018, 09:00   #8
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 168
Репутация: 39
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
ReadBlock- функция
SetLength(FChildBlock,FSizeBlock);
TextAll :=string.Create(FChildBlock,0,ReadB lock(FChildBlock,FSizeBlock))
Спасибо, помогло. Вопрос закрыт.
__________________
Пишу много и развернуто
Heneken87 вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
реализовать метод Эйлера и метод Рунге-Кутте 4-ого порядка на языке С++ Janny2014 Помощь студентам 1 27.11.2013 05:23
Метод перебора, Метод дихотомии, Метод золотого сечения Delphi !!! OneBri Помощь студентам 0 03.10.2012 08:42
исследовать метод квадратных корней и метод Холецкого для решения СЛАУ Vит@x@ Помощь студентам 0 22.11.2011 10:47
Задача Коммивояжера. Метод Монте-Карло и метод приращений. [Паскаль] U9110 Помощь студентам 4 06.04.2011 09:48
Turbo Pascal[програмыки : текстовая\метод симпсона\метод половинного деления qsccsq Помощь студентам 7 24.12.2010 06:23


04:56.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru