Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Lazarus: построчное чтение данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Мужики,
понадобилось читать и писать вывод запускаемой внешней программы (примерно как в этом примере) в наследник TStrings построчно, а не прочтенными блоками. Причем чтение должно осуществляться из пополняемого в это время контейнера/памяти (а не как в выше приведенном примере, после окончания отработки внешней программы).

Подскажите, плз, в каком направлении двигаться? Может ссылки на материал, который можно почитать?
=================
Док.

Win7 Ultim x64/Deb 10 (MATE; gtk3) amd64:
FB 3.0.4.33054, Lazarus 2.1(r.61313); FPC 3.3.1 (r.42151), IBX by -Rik-
2 сен 19, 17:32    [21962076]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Док,

Так в примере же есть поблочное чтение. Остаётся только найти окончание строки и скопировать её. Если читаешь на виндах, то вывод необходимо сначала перекодировать OemToAnsi.
2 сен 19, 17:46    [21962082]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Kazantsev Alexey
Так в примере же есть поблочное чтение.

в примере все телодвижения начинаются лишь после того, как запись в память закончена, а мне бы понять, как из постоянно пополняемого MemoryStream читать и парсить строки. Пока не догоняю...
2 сен 19, 18:38    [21962107]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Док,

Вот там чтение блока:
BytesRead := AProcess.Output.Read(Buffer, BUF_SIZE);

Блок прочитал, ищи конец строки. Не нашёл, складывай данные в накопительный буффер. Нашёл - клади часть данных до маркера новой строки в накопительный буффер и конвертируй накопительный буффер в строку. Накопительный буффер сделай строковым:
type
 OEMString = type AnsiString(CP_OEMCP);
var
 accBfr : OEMString;

Потом строку получишь приведением типа: string(accBuf);
2 сен 19, 18:50    [21962114]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
+ Моя процедура выделения строки. Для дельфей.
//
Procedure TBuilder.ParseDccOutput(Const ABuffer; ACount : Integer);
Var

 CPos       : MarshaledAString; // PAnsiChar;
 Index      : Integer;
 StartIndex : Integer;

 //
 Procedure _AccBuffer(AIndex : Integer);
 Var

  IncSize : Integer;
  OldSize : Integer;

 Begin

  IncSize := AIndex - StartIndex;

  If IncSize > 0 Then
   Begin

    OldSize := Length(FBuffer);
    SetLength(FBuffer, OldSize + IncSize);

    CopyMem(PByte(@ABuffer) + StartIndex, PByte(FBuffer) + OldSize, IncSize);

   End;

  StartIndex := AIndex + 1;

 End;
 //

 //
 Procedure _ProcessLine;
 Begin

  _AccBuffer(Index);

  Try

   ProcessDccLine(String(FBuffer)); // Твоя обработка готовой строки

  Finally

   FBuffer := ''; // тот самый накопительный буфер

  End;

 End;
 //

Begin

 CPos       := @ABuffer;
 Index      := 0;
 StartIndex := 0;

 For Index := 0 To ACount - 1 Do
  Begin

   Case CPos[Index] Of

    #10 : Begin

           If FLastChar = 13 Then
            Inc(StartIndex)
           Else
            _ProcessLine;

          End;

    #13 : _ProcessLine;

   End;

   FLastChar := Ord(CPos[Index]); // FLastChar : Byte;

  End;

 _AccBuffer(ACount);

End;
//
2 сен 19, 18:57    [21962119]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Kazantsev Alexey,

спасибо, смотрю...
2 сен 19, 20:36    [21962141]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
stanilar
Member

Откуда: Спб
Сообщений: 822
Memory Mapped File

Вроде как даже рекомендованный способ совместного доступа к одному файлу. Или он базируется на нем.

В свое время накатал исходник по расширению менеджера памяти для датасета. Собирался к лазарю прикрутить... Но вот времени не было сделать, а теперь уже бывший дельфиец...
3 сен 19, 16:42    [21962682]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Василий 2
Member

Откуда:
Сообщений: 700
Есть же TStringReader
4 сен 19, 10:14    [21963034]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
vavan
Member

Откуда: Казань
Сообщений: 3365
stanilar
расширению менеджера памяти для датасета
не поясните о чем речь?
4 сен 19, 10:36    [21963055]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5107
Док,

обычно автомат делают

несмотря на всю теорию, на практике в простейших случаях как этот, это обычно набор Case в которых происходит установка текущего состояния

у вас ещё и под разные платформы, так что стоит сразу заложиться на все возможные разделители #13, #10, #10#13


если номер строчки неважен, то можно считать любой из символов #13 или #10 разделителем и если аддитивный буфер непустой считать его новой строкой
4 сен 19, 11:08    [21963097]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 638
kealon(Ruslan)
у вас ещё и под разные платформы, так что стоит сразу заложиться на все возможные разделители #13, #10, #10#13


sLineBreak же.
4 сен 19, 11:34    [21963141]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5107
Vizit0r,

даже мелкомягкие иногда просто #13 или #10 скидывают, и такие сбои нужно обрабатывать корректно
4 сен 19, 11:40    [21963160]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
kealon(Ruslan)
стоит сразу заложиться на все возможные разделители #13, #10, #10#13

В моём варианте, как раз, поддерживается #10, #13, #13#10.
4 сен 19, 11:51    [21963188]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Kazantsev Alexey,

спасибо за пинок в нужном направлении. Правда, для простоты я реализовал через строки, а не через указатели (скорость выполнения дял меня не критична, в моих задачах не планируется длинный вывод). Выглядит примерно так (пояснения в тексте для себя-склеротика и нубов, которые будут читать код после меня. "Лишние" переменные остались после отладки, в итоговом коде почищу)

+
procedure TForm1.btnGoClick(Sender: TObject);
{$IFDEF MSWINDOWS}
type
  WinCpString = type AnsiString(CP_ACP);//uses LConvEncoding
{$ENDIF}
const
  BUF_SIZE = 1024*2; // Размер буфера для чтения выходных данных блоками
var
  {$IFDEF MSWINDOWS}
  Buffer: WinCpString = '';
  {$ELSE}
  Buffer: string = '';
  {$ENDIF}

  DebugStr: String = '';//отладочная строка
  BufferStr: String = '';//буфер-накопитель
  BytesRead: LongInt = 0;//кол-во считанных из буфера байт
  LineEndingPos: Integer = 0;//позиция начала перевода строки
  StrPartLineEndingAhead //часть строки до LineEnding
  , StrPartLineEndingBehind //часть строки после LineEnding
                :String;
  StrCounter: Integer = 0;//счетчик выводимых memoOutput строк
begin
  memoOutput.Clear;

  {$IFDEF MSWINDOWS}
  // В Windows команду dir нельзя использовать напрямую, потому что она является встроенной
  // командой оболочки. Поэтому нужны cmd.exe и дополнительные параметры
  AProcess.Executable := 'c:\windows\system32\cmd.exe';
  AProcess.Parameters.Add('/c');
  AProcess.Parameters.Add('dir /s c:\Windows\System32\drivers');
  {$ENDIF}
  {$IFDEF UNIX}
  AProcess.Executable := '/bin/ls';
  AProcess.Parameters.Add('--recursive');
  AProcess.Parameters.Add('--all');
  AProcess.Parameters.Add('-l');
  {$ENDIF}

  AProcess.Options := [poUsePipes, poStderrToOutPut, poNoConsole];

  //Запуск процесса (выполнение команды dir/ls)
  AProcess.Execute;

  StrPartLineEndingAhead:= '';
  StrPartLineEndingBehind:= '';
  repeat
    memoOutput.Lines.BeginUpdate;
    try
      SetLength(Buffer,BUF_SIZE);//задаем минимальный размер Buffer (как правило размер Pipes в ОС не превышает 2kB)
      BytesRead := AProcess.Output.Read(Buffer[1],Length(Buffer));//читаем в Buffer и получаем кол-во считанных байт BytesRead;
      if BytesRead > 0
      then
        begin
          SetLength(Buffer,BytesRead);
          DebugStr:= CP1251ToUTF8(Buffer);//uses LConvEncoding

          {LineEnding - алиас для sLineBreak:
          Win = #13#10
          Unix = #10
          Mac OS до v.9 = #13}

          //получаем позицию LineEnding в строке
          LineEndingPos:= UTF8Pos(LineEnding,CP1251ToUTF8(Buffer)); //uses LazUTF8

          if LineEndingPos > 0
          then
            repeat
              if LineEndingPos = 1 //LineEnding в начале строки
              then
                begin
                  StrPartLineEndingAhead:= UTF8Copy(DebugStr,1, UTF8Length(LineEnding));//по сути присвоим пустую строку ''
                  Inc(StrCounter);
                  memoOutput.Lines.Add(Format('%d.',[StrCounter]));//добавляем в memoOutput пустую строку
                end
              else //LineEnding не в начале строки
                begin
                  StrPartLineEndingAhead:= UTF8Copy(DebugStr,1, LineEndingPos - 1);//захватываем часть строки до LineEndingPos;
                  BufferStr:= BufferStr + StrPartLineEndingAhead;// добавляем к строке-буферу захваченный до LineEnding текст
                  Inc(StrCounter);
                  memoOutput.Lines.Add(Format('%d. %s',[StrCounter, BufferStr]));//пишем буфер-накопитель в memoOutput
                  BufferStr:= '';//и "обнуляем" его для следующей итерации
                end;

              //захватываем оставшуюся часть строки после LineEndingPos без символов LineEnding
              StrPartLineEndingBehind:= UTF8Copy(DebugStr,LineEndingPos + UTF8Length(LineEnding), UTF8Length(DebugStr));

              DebugStr:= StrPartLineEndingBehind;
              LineEndingPos:= UTF8Pos(LineEnding,DebugStr);
            until LineEndingPos = 0
          else //LineEnding в DebugStr отсутствует 
            begin
             BufferStr:= BufferStr + DebugStr;
             Inc(StrCounter);
             memoOutput.Lines.Add(Format('%d. %s',[StrCounter, BufferStr]));//пишем строку-буфер в memoOutput
            end;
        end;
    finally
      memoOutput.Lines.EndUpdate;
      memoOutput.SelStart := UTF8Length(memoOutput.Text);
    end;
    Sleep(10);
    Application.ProcessMessages;
  until BytesRead = 0;
end;      

Возможно, есть ошибки в коде. Если найду, поправлю.

К сообщению приложен файл. Размер - 34Kb
4 сен 19, 12:07    [21963222]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Док,

Хапнешь горя, когда дефотные строки перестанут быть байтовыми.
4 сен 19, 12:54    [21963322]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

кстати, не помешает наверное ещё и по таймауту забирать то, что ещё не завершено #10, #13, #13#10.

Posted via ActualForum NNTP Server 1.5

4 сен 19, 13:05    [21963340]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Kazantsev Alexey
Хапнешь горя, когда дефолтные строки перестанут быть байтовыми.

можно подробнее, о каких строках речь и какими они станут? НЕ ОДНОбайтовыми, ты имеешь ввиду?

Мимопроходящий
кстати, не помешает наверное ещё и по таймауту забирать то, что ещё не завершено #10, #13, #13#10

не совсем догнал - где?
4 сен 19, 14:25    [21963464]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Док
можно подробнее, о каких строках речь и какими они станут? НЕ ОДНОбайтовыми, ты имеешь ввиду?

О дефолтном String, он будет юникодовым в ближайшей перспективе.
4 сен 19, 15:09    [21963531]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

04.09.2019 15:09, Kazantsev Alexey пишет:
> О дефолтном String, он будет юникодовым в ближайшей перспективе.

в Лазаре utf8.
а Док на нём и сидит.

Posted via ActualForum NNTP Server 1.5

4 сен 19, 15:40    [21963586]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

04.09.2019 14:25, Док пишет:

МП>> кстати, не помешает наверное ещё и по таймауту забирать то, что ещё не завершено #10, #13, #13#10
> не совсем догнал - где?

если я правильно понял твою задачу, ты тащишь данные, которые процесс вываливает в консоль по "трубе".
может так случиться, что ты получил из "трубы" последовательность, которая не заканчивается #10, #13, #13#10
а процесс, который ты отслеживаешь, ничего больше не шлёт (пока).
в этом случае ты этого кусочка можешь ждать ооооооочень долго...

Posted via ActualForum NNTP Server 1.5

4 сен 19, 15:45    [21963594]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Мимопроходящий,

Строковый тип определяется не лазарем, а в фпц он скоро будет юникодовым по дефолту.
4 сен 19, 15:49    [21963599]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Кстати, уже и лазарь готовится к utf-16.
4 сен 19, 15:58    [21963615]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
The goal of FPC project is [/b]to create a Delphi compatible UnicodeString (UTF-16) based solution[/b], but it is not ready yet. It may take some time to be ready.

This UTF-8 solution of LCL in its current form can be considered temporary. In the future, when FPC supports UnicodeString fully in RTL and FCL, Lazarus project will provide a solution for LCL that uses it. At the same time the goal is to preserve UTF-8 support although it may require changes to string types or something. Nobody know the details yet. We will tell when we know...

In essence LCL will probably have 2 versions, one for UTF-8 and one for UTF-16.


Так что, использование конкретизированного строкового типа не просто доброе пожелание, это маст хэв.
4 сен 19, 16:02    [21963621]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

дважды дибилы!

Posted via ActualForum NNTP Server 1.5

4 сен 19, 16:08    [21963630]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Мимопроходящий
может так случиться, что ты получил из "трубы" последовательность, которая не заканчивается #10, #13, #13#10

так я в коде вроде бы учел этот момент. Нет?
+
          if LineEndingPos > 0
          then
            repeat
            <skiped>
            until LineEndingPos = 0
          else //LineEnding в DebugStr отсутствует 
            begin

Не уверен, но repeat..until в операторные скобки заключать же не надо?

зы. вообще, я пишу для себя кроссплатформенную утилитку с использованием gbak/gfix/gstat/isql - покатаю код еще там...

Kazantsev Alexey
Так что, использование конкретизированного строкового типа не просто доброе пожелание, это маст хэв.

если я правильно тебя понял, все упирается в то, какого типа строка в фпц на момент сборки кода.

Ну дык я же везде повтыкал UTF8-аналоги функций работы со строками, которые корректно работают как с UTF8, так и с ansi. Наверняка, в момент перехода на utf16 окончательно обновятся и аналогичные UTF16-функции, которые (весьма вероятно) будут корректно работать со всеми ansi/utf8/utf16 строками. Вся беда в том, что
автор
...Nobody know the details yet. We will tell when we know...


Или я не так тебя понял и опять чего-то не догоняю?

ps. надеюсь #13 и #10 при любой погоде остануться однобайтными Картинка с другого сайта.. Иначе придется, как в Дельфях, из CodePointSize/UTF8CodepointSize городить огород.
4 сен 19, 16:34    [21963654]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
s62
Member

Откуда: Жуковский
Сообщений: 988
Док
...
ps. надеюсь #13 и #10 при любой погоде остануться однобайтными Картинка с другого сайта.. Иначе придется, как в Дельфях, из CodePointSize/UTF8CodepointSize городить огород.

Напрасно надеешься :)

К сообщению приложен файл. Размер - 4Kb
4 сен 19, 16:49    [21963679]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5107
Док
ps. надеюсь #13 и #10 при любой погоде остануться однобайтными Картинка с другого сайта.. Иначе придется, как в Дельфях, из CodePointSize/UTF8CodepointSize городить огород.
вход с консоли останется тот же, однобайтный - тут ничего не поменяется надеюсь
4 сен 19, 16:49    [21963680]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Док
если я правильно тебя понял, все упирается в то, какого типа строка в фпц на момент сборки кода.

Именно. У тебя под буфер для винды используется конкретизированный тип, а для прочих систем дефолтный. Однако, буфер то байтовый.

Кстати, у тебя там поиск маркера конца строки сможет обработать ситуацию, когда пара #13#10 будет разделена?
4 сен 19, 16:57    [21963695]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
И вообще, зря ты со строками связался...
4 сен 19, 16:58    [21963696]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
ёёёёё
Member

Откуда:
Сообщений: 688
Док
Мужики,
понадобилось читать и писать вывод запускаемой внешней программы...

Задача именно в такой постановке? Нельзя что-то более вменяемое для обмена данными организовать?
4 сен 19, 17:01    [21963698]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Kazantsev Alexey
Кстати, у тебя там поиск маркера конца строки сможет обработать ситуацию, когда пара #13#10 будет разделена?

так вот, почему у тебя сначала #13 ищется, а потом #10. Таки придется от строк отказываться Картинка с другого сайта.

ёёёёё
Нельзя что-то более вменяемое для обмена данными организовать?

ты меня спрашиваешь? Название топика читал? Это я спросил совета, в надежде на твой ответ :)
4 сен 19, 17:11    [21963711]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

04.09.2019 16:34, Док пишет:

МП>> может так случиться, что ты получил из "трубы" последовательность, которая не заканчивается #10, #13, #13#10
> так я в коде вроде бы учел этот момент. Нет?

я твой код не вижу.
ты его в спойлер прячешь.
по NNTP оно не отображается.
а вообще, спойлеры для того, чтоб в них прятать женскую половую письку.
а не код, на техническом форуме.

> зы. вообще, я пишу для себя кроссплатформенную утилитку с использованием gbak/gfix/gstat/isql - покатаю код еще там...

все эти "кроссы" от лукавого.

Posted via ActualForum NNTP Server 1.5

4 сен 19, 17:13    [21963714]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Мимопроходящий
ты его в спойлер прячешь.
по NNTP оно не отображается.

"вон оно че, Михалыч" ©

а я пальцы и колесико мышки читающих берегу. Не люблю портянки кода на 3 экрана :)

Мимопроходящий
все эти "кроссы" от лукавого.

ага, ты это юзверю объясни, который то в лине, то в иосе чего-то там делает :)
4 сен 19, 17:31    [21963744]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

04.09.2019 17:31, Док пишет:

МП>> все эти "кроссы" от лукавого.
> ага, ты это юзверю объясни, который то в лине, то в иосе чего-то там делает :)

но gbak-и то есть и для линуха, и для винды.
а под яось нет и не будет.

Posted via ActualForum NNTP Server 1.5

4 сен 19, 17:49    [21963763]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Мимопроходящий
но gbak-и то есть и для линуха, и для винды.
а под яось нет и не будет.

сегодня для меня день открытий :)
4 сен 19, 18:19    [21963789]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
stanilar
Member

Откуда: Спб
Сообщений: 822
vavan
не поясните о чем речь?

На тот случай, когда из базы приходит больше двух(четырех) гигов.
5 сен 19, 09:53    [21964256]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
vavan
Member

Откуда: Казань
Сообщений: 3365
Док
Мимопроходящий
все эти "кроссы" от лукавого.

ага, ты это юзверю объясни, который то в лине, то в иосе чего-то там делает
да вполне типичная ситуация для кучи проектов к-е из одной кодовой базы собираются и работают как под вынь так и хрюндиксы. я вот сервисы и туда и сюда собираю из vs, правда ни разу не морды так что иосы к счастью не беспокоят
5 сен 19, 09:56    [21964258]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
vavan
Member

Откуда: Казань
Сообщений: 3365
stanilar
На тот случай, когда из базы приходит больше двух(четырех) гигов
любопытно, жаль на посмотреть не выложено ведь?
5 сен 19, 09:58    [21964263]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
stanilar
Member

Откуда: Спб
Сообщений: 822
vavan
любопытно, жаль на посмотреть не выложено ведь?

stanilar
Но вот времени не было сделать, а теперь уже бывший дельфиец...


Нет, как уже было сказано, не выложено. Но время было интересное. Был молод, думал что знания о том, как работает менеджер памяти равносильно успеху в жизни. Все делал в поте лица. Правда, мне самому так и осталось не понятным, помогло-ли(потому и не стал выкладывать). А теперь уже нет ни времени дальше разбираться, ни желания копаться в том, что больше никогда не понадобится. Осталась только ностальгия по ушедшему без пользы.

P/S/ Могу выслать почтой то, что (возможно) было тем, о чем идет речь. Идея была в том, что DS работает с памятью аналогично TStream. Вот и был сделан наследник TStream для кэша DS, который окном в 64Кб читал/писал кэш. Сам наследник это отдельный компонент, а вот как хакнуть DS из родных библиотек это два сторонних компонента + танцы с бубном.
5 сен 19, 11:32    [21964358]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
vavan
Member

Откуда: Казань
Сообщений: 3365
stanilar
Могу выслать почтой то, что (возможно) было тем, о чем идет речь
+
в профиле ящик актуальный?
5 сен 19, 11:52    [21964383]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
stanilar
Member

Откуда: Спб
Сообщений: 822
vavan,

+
Да, только тему нужно написать читаемую, а то этот ящик у меня для всего. Пошел копать исходники
5 сен 19, 12:00    [21964390]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
vavan
Member

Откуда: Казань
Сообщений: 3365
stanilar,
+
в заголовке sql.ru
если таки разыщется и не жалко то я бы глянул из любопытства о чем речь. спасибо
5 сен 19, 12:39    [21964437]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
ёёёёё
Member

Откуда:
Сообщений: 688
Док
...

ёёёёё
Нельзя что-то более вменяемое для обмена данными организовать?

ты меня спрашиваешь? Название топика читал? Это я спросил совета, в надежде на твой ответ :)

Ну я не знал, что тебе бэкап/рестор нужен FB. Поди из стартового топика пойми. Я вот в клиентское приложение встроил и бэкап, и рестор. Используя соотв. компоненты библиотеки доступа. И никакого чтения из памяти, десяток строк кода, и все.
Или тебе прямо обязательно именно в твоей постановке задачу решать?
5 сен 19, 12:46    [21964447]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30273

05.09.2019 12:46, ёёёёё пишет:
> Я вот в клиентское приложение встроил и бэкап, и рестор.
> Используя соотв. компоненты библиотеки доступа.

через TIBServices ты НЕ можешь получить бекап с удалённого сервера себе "у папочку" на десктопе.

Posted via ActualForum NNTP Server 1.5

5 сен 19, 14:09    [21964580]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
ёёёёё
Member

Откуда:
Сообщений: 688
Мимопроходящий,

это да, но нужно ли сие топикстартеру?

ЗЫ: как-то делал копирование удаленной базы на локальный комп, тоже совсем немного работы: за основу взял пример "клонирование базы" из состава икземплов к UIB. Чуть доточил для фич новой СУБД, результаты сравнивал в DB Comparer.
5 сен 19, 14:23    [21964598]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
ёёёёё
Ну я не знал, что тебе бэкап/рестор нужен FB. Поди из стартового топика пойми. Я вот в клиентское приложение встроил и бэкап, и рестор. Используя соотв. компоненты библиотеки доступа. И никакого чтения из памяти, десяток строк кода, и все.

птицын b/r - это частный случай, который запросто решается в случае получения ответа на вопрос стартового топика.

Мимопроходящий
через TIBServices ты НЕ можешь получить бекап с удалённого сервера себе "у папочку" на десктопе.


Компоненты - оне пишутся компонентописателями. Тот IBX, который сейчас репах Лазаревского OPM, усиленно пилится и даже теперь позволяет динамически грузить клиентскую библу, как это делали ФИБы. Причем, он, автор, разделил свои компоненты условно на legacy (которые позволяли делать b/r только на стороне сервера) и современные (эти теоретически позволяют все), но они еще кривые, автор - обладает весьма большой инертностью и упрямством; пока его убедишь поправить тот или иной косяк, особенно, если он в этом не убежден .... :)

Посему проще написать свою гуишную обертку (к тому же, всегда есть возможность прикрутить к ней все новые фишки). И в простом варианте я это сделал, но хочется большего функционала красивостей, нежели есть в IBE, и проч.проч.
5 сен 19, 15:41    [21964699]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
ёёёёё
Member

Откуда:
Сообщений: 688
Док,
автор
птицын b/r - это частный случай, который запросто решается в случае получения ответа на вопрос стартового топика.

Страшно представить, что ты затеял.
5 сен 19, 16:04    [21964729]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Док
Member

Откуда: Казань
Сообщений: 6341
Во, наконец-то сегодня руки дошли. Код специально не прячу под спойлер для читающих по NNTP. Кому нетрудно, погоняйте у себя, плз (проект приаттачил) - теоретически должен работать и под стабильные Лазарь и фпц.

procedure TForm1.btnGoClick(Sender: TObject);
const
  BUF_SIZE = 1024*2; // Размер буфера для чтения выходных данных блоками
  ConstFormatStr = '%d. ~ %s';//строка формата для подстановки вывода текста в мемо
var
{$IFDEF MSWINDOWS}
Buffer: RawByteString = '';
BufferStg: RawByteString = '';//буфер-накопитель
{$ENDIF}
{$IFDEF UNIX}
Buffer: String = '';
BufferStg: String = '';//буфер-накопитель
{$ENDIF}
  StrCounter: Integer = 0;//счетчик выводимых memoOutput строк
  BytesRead: LongInt = 0;//кол-во считанных из буфера байт
  LineEndingPos_13: Integer = 0;//позиция символа возврата каретки #13(CR)
  LineEndingPos_10: Integer = 0;//позиция символа перевода строки #10(CR)
  dt: TDateTime;
begin
  memoOutput.Clear;

  {$IFDEF MSWINDOWS}
  // В Windows команду dir нельзя использовать напрямую, потому что она является встроенной
  // командой оболочки. Поэтому нужны cmd.exe и дополнительные параметры
  AProcess.Executable := 'c:\windows\system32\cmd.exe';
  AProcess.Parameters.Add('/c');
  AProcess.Parameters.Add('dir /s c:\windows\system32');
  {$ENDIF}
  {$IFDEF UNIX}
  AProcess.Executable := '/bin/ls';
  AProcess.Parameters.Add('--recursive');
  AProcess.Parameters.Add('--all');
  AProcess.Parameters.Add('-l');
  {$ENDIF}

  AProcess.Options := [poUsePipes, poStderrToOutPut, poNoConsole];

  //Запуск процесса (выполнение команды dir/ls)
  AProcess.Execute;

  dt:= Now;
  memoOutput.Lines.Add('==== процесс начат: ' + FormatDateTime('dd.mm.yyyy h:mm:ss:zzz am/pm',dt) + ' ====');
  memoOutput.Lines.Add('');

  SetLength(Buffer,BUF_SIZE);//задаем минимальный размер Buffer (как правило размер Pipes в ОС не превышает 2kB)
  BytesRead:= AProcess.Output.Read(Buffer[1],Length(Buffer));//читаем в Buffer и получаем кол-во считанных байт BytesRead;

  repeat
    memoOutput.Lines.BeginUpdate;
    try
      if BytesRead > 0 then
      begin
        SetLength(Buffer,BytesRead);

        {LineEnding - алиас для sLineBreak:
        Win = #13#10
        Unix = #10
        Mac OS до v.9 = #13}

        {$IFDEF MSWINDOWS}
        //получаем позицию #13 в строке
        LineEndingPos_13:= Pos(#13,Buffer);

        repeat
          case LineEndingPos_13 of
            0:
              begin
                BufferStg:= BufferStg + Buffer;
              end;
            1://#13 в начале строки
              begin
                LineEndingPos_10:= Pos(#10, Buffer);

                case (LineEndingPos_10 - LineEndingPos_13) of
                  1: //#10(LF) следует за #13(CR)
                    begin
                      Inc(StrCounter);
                      //сбрасываем буфер-хранилище в memo...
                      memoOutput.Lines.Add(Format(ConstFormatStr,[StrCounter,WinCPToUTF8(BufferStg)]));

                      //очищаем буфер-хранилище
                      BufferStg:='';

                      //откусываем от начала буфера символы перевода строки #13#10(CRLF)
                      Delete(Buffer,1,2); //... и крутим цикл дальше
                    end;
                  else //после #13(CR) следует любой символ, кроме #10(LF), или нет вообще символов
                    begin
                      //клеим символ возврата каретки #13(CR) к буферу-накопителю
                      BufferStg:= BufferStg + #13;

                      //откусываем от начала буфера символ возврата каретки #13(CR)
                      Delete(Buffer,1,1); //... и крутим цикл дальше
                    end;
                  end;
              end;
            else //#13(CR) в середине или в конце буфера
              LineEndingPos_10:= Pos(#10, Buffer);
              case (LineEndingPos_10 - LineEndingPos_13) of
                1: //#10(LF) следует за #13(CR)
                  begin
                    //копируем часть буфера до #13(CR) в буфер-хранилище
                    BufferStg:= BufferStg + Copy(Buffer,1,LineEndingPos_13 - 1);

                    Inc(StrCounter);

                    //сбрасываем буфер-хранилище в memo...
                    memoOutput.Lines.Add(Format(ConstFormatStr,[StrCounter,WinCPToUTF8(BufferStg)]));

                    //очищаем буфер-хранилище
                    BufferStg:='';

                    //отрезаем спереди часть буфера вместе BufferStg + символами перевода строки #13#10(CRLF)
                    Delete(Buffer,1, LineEndingPos_13 + 1);//... и крутим цикл дальше
                  end;
                else //после #13(CR) следует любой символ, кроме #10(LF), или нет вообще символов
                  begin
                    //клеим его к буферу-накопителю
                    BufferStg:= BufferStg + #13;

                    //откусываем от начала буфера символ возврата каретки #13(CR)
                    Delete(Buffer,1,1);//... и крутим цикл дальше
                  end;
              end;
          end;
          LineEndingPos_13:= Pos(#13,PChar(Buffer));
        until LineEndingPos_13 = 0;
        {$ENDIF}
        {$IFDEF UNIX}
        //получаем позицию #10 в строке
        LineEndingPos_10:= Pos(#10,Buffer);

        repeat
          case LineEndingPos_10 of
            0:
              begin
                BufferStg:= BufferStg + Buffer;
              end;
            1: //#10 в начале строки
              begin
                Inc(StrCounter);
                //сбрасываем буфер-хранилище в memo...
                memoOutput.Lines.Add(Format(ConstFormatStr,[StrCounter,BufferStg]));

                //очищаем буфер-хранилище
                BufferStg:='';

                //откусываем от начала буфера символ перевода строки #10(LF)
                Delete(Buffer,1,1);

                //... и крутим цикл дальше
              end
            else //#10(LF) в середине или в конце буфера
              begin
                //копируем часть Buffer до #10(LF) в буфер-накопитель
                BufferStg:= BufferStg + Copy(Buffer,1,LineEndingPos_10 - 1);

                Inc(StrCounter);
                //сбрасываем буфер-хранилище в memo...
                memoOutput.Lines.Add(Format(ConstFormatStr,[StrCounter,BufferStg]));


                //очищаем буфер-хранилище
                BufferStg:='';

                //отрезаем спереди часть буфера вместе BufferStg + символом перевода строки #10(LF)
                Delete(Buffer,1,LineEndingPos_10);

                //... и крутим цикл дальше
              end;
          end;
          LineEndingPos_10:= Pos(#10,Buffer);
        until LineEndingPos_10 = 0;
        {$ENDIF}
      end;
    finally
      memoOutput.Lines.EndUpdate;
      memoOutput.SelStart := UTF8Length(memoOutput.Text);
    end;
    Sleep(10);
    Application.ProcessMessages;

    SetLength(Buffer,BUF_SIZE);
    BytesRead:= AProcess.Output.Read(Buffer[1],Length(Buffer));//читаем в Buffer и получаем кол-во считанных байт BytesRead;
  until BytesRead = 0;

  //сливаем остатки буфера-накопителя в Мемо
  if Length(BufferStg) > 0 then
  begin
    Inc(StrCounter);
    //сбрасываем буфер-хранилище в memo...
    {$IFDEF MSWINDOWS}
    memoOutput.Lines.Add(Format(ConstFormatStr,[StrCounter,BufferStg]));
    {$ENDIF}
    {$IFDEF UNIX}
    memoOutput.Lines.Add(Format(ConstFormatStr,[StrCounter,BufferStg]));
    {$ENDIF}

  end;
  dt:= Now;
  memoOutput.Lines.Add('');
  memoOutput.Lines.Add('==== процесс закончен: ' + FormatDateTime('dd.mm.yyyy h:mm:ss:zzz am/pm',dt) + ' ====');
end;


@Kazantsev Alexey

че-та не стал я заморачиваться с байтами (в отладке сложнее), со строками проще, тем более, что StringElementSize для стрингов в *nix'ах равен все равно равен StringElementSize для RawByteString под винды. Если покажешь пример, буду благодарен. :)

К сообщению приложен файл (project1.zip - 107Kb) cкачать
12 сен 19, 16:23    [21969638]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте с построчным чтением данных из памяти  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3717
Док
че-та не стал я заморачиваться с байтами (в отладке сложнее), со строками проще

Чего там отлаживать, прости господи... Хотя, дело хозяйское, конечно.

Док
тем более, что StringElementSize для стрингов в *nix'ах равен все равно равен StringElementSize для RawByteString под винды

Пока равен.
12 сен 19, 18:38    [21969746]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Delphi Ответить