Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

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

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

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.06.2018, 09:48   #1
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию 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 в 09:58.
Heneken87 вне форума Ответить с цитированием
Старый 21.06.2018, 10:33   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

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

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

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

Спасибо за быстрый ответ.
Цитата:
Сообщение от 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, 11:38   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

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

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

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

Цитата:
Сообщение от 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 в 11:52.
Heneken87 вне форума Ответить с цитированием
Старый 21.06.2018, 11:56   #6
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 219
По умолчанию

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

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

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


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
реализовать метод Эйлера и метод Рунге-Кутте 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 05:23