Хэндл -> файловая переменная ?

Полуламер
Дата: 25.05.2011 17:57:04
Доброго времени! У меня затруднение в решении одной проблемы и также неясно, разрешима ли она вообще. Посему хотел бы спросить совета у знающих людей. Значит, так - бинарный файл открывается с помощью FileOpen и потом с ним осуществляются разные операции, в т.ч. FileSeek и FileRead. Есть пример функции, достаточно быстро ищущей определенный контекст в бинарнике, точнее, его позицию в этом файле:

function ScanFile(const FileName: string;
  const forString: string;
  caseSensitive: Boolean): Longint;
const
  BufferSize = $8001;  { 32K+1 bytes }
var
  pBuf, pEnd, pScan, pPos: PChar;
  filesize: LongInt;
  bytesRemaining: LongInt;
  bytesToRead: Integer;
  F: file;
  SearchFor: PChar;
  oldMode: Word;
begin
  { assume failure }
  Result := -1;
  if (Length(forString) = 0) or (Length(FileName) = 0) then Exit;
  SearchFor := nil;
  pBuf      := nil;

   { open file as binary, 1 byte recordsize }
  AssignFile(F, FileName);
  oldMode  := FileMode;
  FileMode := 0;    { read-only access }

  Reset(F, 1);

  FileMode := oldMode;
  try { allocate memory for buffer and pchar search string }
    SearchFor := StrAlloc(Length(forString) + 1);
    StrPCopy(SearchFor, forString);
    if not caseSensitive then  { convert to upper case }
      AnsiUpper(SearchFor);
    GetMem(pBuf, BufferSize);
    filesize       := System.Filesize(F);
    bytesRemaining := filesize;
    pPos           := nil;
    while bytesRemaining > 0 do
    begin
      { calc how many bytes to read this round }
      if bytesRemaining >= BufferSize then
        bytesToRead := Pred(BufferSize)
      else
        bytesToRead := bytesRemaining;
      { read a buffer full and zero-terminate the buffer }
      BlockRead(F, pBuf^, bytesToRead, bytesToRead);
      pEnd  := @pBuf[bytesToRead];
      pEnd^ := #0;
      pScan := pBuf;
      while pScan < pEnd do
      begin
        if not caseSensitive then { convert to upper case }
          AnsiUpper(pScan);
        pPos := StrPos(pScan, SearchFor);  { search for substring }
        if pPos <> nil then
        begin { Found it! }
          Result := FileSize - bytesRemaining +
            Longint(pPos) - Longint(pBuf);
          Break;
        end;
        pScan := StrEnd(pScan);
        Inc(pScan);
      end;
      if pPos <> nil then Break;
      bytesRemaining := bytesRemaining - bytesToRead;
      if bytesRemaining > 0 then
      begin
        Seek(F, FilePos(F) - Length(forString));
        bytesRemaining := bytesRemaining + Length(forString);
      end;
    end; { While }
  finally

  CloseFile(F);

    if SearchFor <> nil then StrDispose(SearchFor);
    if pBuf <> nil then FreeMem(pBuf, BufferSize);
  end;
end;

Сразу хочу пояснить во избежание вопросов - бинарником я называю обычный PDF-файл, созданный определенной программой (в данном случае LaTeX), все делается с единственной целью - вытащить из файла примитивным образом информацию об авторе, заголовке и т.д., то есть из четырех инфо-полей , которые видно при просмотре PDF в том же Adobe PDF Reader. Вышеозначенная функция, как уже сказано, рыщет по файлу и возвращает позицию инфо-поля, а уж потом с помощью основной программы вытягиваются данные. По идее все как бы работает - сначала открыл PDF с помощью Assign / Reset, нашел позицию одного поля, закрыл PDF; потом опять открыл PDF с помощью FileOpen, выудил инфу, закрыл PDF. Итого целых четыре операции, а для четырех полей их получается уже шестнадцать! :( В общем, ни уму, ни сердцу. Функция поиска знает хэндл открытого файла, но она использует нетипизированную файловую переменную и естественно файл этот уже занят основной программой. Поэтому вопрос из заголовка - можно ли как-то преобразовать хэндл в файловую переменную, чтобы поисковая функция уже знала, что это тот самый файл и что он открыт для чтения? Заранее извиняюсь за возможно глупый вопрос.
MikleBess
Дата: 25.05.2011 18:54:30
А если
F: file;
и функции открытия/закрытия файла вынести из функции, может поможет...
Dimitry Sibiryakov
Дата: 25.05.2011 19:08:52

Полуламер
По идее все как бы работает - сначала открыл PDF с помощью Assign / Reset, нашел позицию
одного поля, закрыл PDF; потом опять открыл PDF с помощью FileOpen, выудил инфу, закрыл PDF.

А что мешает "выуживать инфу" прямо из файла, открытого Reset-ом?..

Posted via ActualForum NNTP Server 1.4

Полуламер
Дата: 26.05.2011 11:28:32
Dimitry Sibiryakov
А что мешает "выуживать инфу" прямо из файла, открытого Reset-ом?..

И в самом деле - что? Искреннее спасибо за виртуальную затрещину, она избавила меня от истерики на пустом месте. Извиняюсь за поднятый шум - протупил конкретно :-0