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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.12.2021, 00:53   #1
noveek
Пользователь
 
Регистрация: 26.05.2015
Сообщений: 56
По умолчанию Быстрое чтение/запись в файл

Здравствуйте, есть ли возможность очень быстро писать и читать строки с файла сейчас использую Buffered FileStream (доступ к буфферизованным файлам) и пишу обычно Append и это очень медленно на мой взгляд (
Код:
//Читаю n строку с файла так:
uses
BufferedFileStream;
function GrabNew(const AFileName: string; ALine: Integer): string;
var
  fs: TReadOnlyCachedFileStream;
  buf: packed array[0..4096] of Char;
  bufRead: Integer;
  bufPos: PChar;
  lineStart: PChar;
  tmp: string;
begin
  fs := TReadOnlyCachedFileStream.Create(AFileName);
  try
    Dec(ALine);
    bufRead := 0;
    bufPos := nil;

    { read the first line specially }
    if ALine = 0 then
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      if bufRead = 0 then
        raise Exception.Create('Line not found');
        //work:=false;
      bufPos := buf;
    end else
      while ALine > 0 do
      begin
        { read in a buffer }
        bufRead := fs.Read(buf, SizeOf(buf));
        if bufRead = 0 then
          raise Exception.Create('Line not found');
          //work:=false;
        bufPos := buf;
        while (bufRead > 0) and (ALine > 0) do
        begin
          if bufPos^ = #10 then
            Dec(ALine);
          Inc(bufPos);
          Dec(bufRead);
        end;
      end;
    { Found the beginning of the line at bufPos... scan for end.
     2 cases:
       1) we"ll find it before the end of this buffer
       2) it"ll go beyond this buffer and into n more buffers }
    lineStart := bufPos;
    while (bufRead > 0) and (bufPos^ <> #10) do
    begin
      Inc(bufPos);
      Dec(bufRead);
    end;
    { if bufRead is positive, we"ll have found the end and we can leave. }
    SetString(Result, lineStart, bufPos - lineStart);
    { determine if there are more buffers to process }
    while bufRead = 0 do
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      lineStart := buf;
      bufPos := buf;
      while (bufRead > 0) and (bufPos^ <> #10) do
      begin
        Inc(bufPos);
        Dec(bufRead);
      end;
      SetString(tmp, lineStart, bufPos - lineStart);
      Result := Result + tmp;
    end;
  finally
  Freeandnil(fs);

  end;
  delete(Result,length(Result),1);
end;

//Записываю в файл строку так:
if not FileExists (Extractfilepath(paramstr(0))+'log.txt') then begin
Assignfile(Zapros, Extractfilepath(paramstr(0))+'log.txt');
Rewrite(logfile);
Closefile(logfile);
end;
Append(logfile);
Writeln(logfile,logstring);
Closefile(logfile);
Это очень медленно наткнулся на процедуру ассинхронного чтения и записи но оно не работает (
Код:
function AsyncReadFile(const FileName: string;const Overlapped:TOverlapped): cardinal;
const
 BufSize = 1024*1024;
var
 Fi: THandle;
 pBuf:array [0..1] of pointer;//нужно два буфера, в первый читаем, а второй передаем для обработки
 BigSize:array [0..1] of Cardinal;
 Count:array[0..1] of Cardinal;
 index:Cardinal; // определяет в какой буфер читать, а какой передавать на обработку
 Size:^Int64; // размер файла
begin
Result:=$FFFFFFFF;
Fi:=CreateFile(Pchar(FileName),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED or FILE_FLAG_SEQUENTIAL_SCAN,0); //режим доступа асинхронный + просим систему кешировать файл
if Fi = INVALID_HANDLE_VALUE then exit;
GetMem(pBuf[0],BufSize);
GetMem(pBuf[1],BufSize);
if (pBuf[0] = nil)or(pBuf[1] = nil) then  exit;
 BigSize[0]:=GetFileSize(fi,@BigSize[1]); //получаем размер файла
 Size:=@BigSize[0];
if Size^ <> 0 then
begin
index:=0;
//первоче чтение
 count[index and 1]:=BufSize;
 if Size^ < BufSize then count[index and 1]:=Size^;
   ResetEvent(Overlapped.hEvent);
   ReadFile(Fi,pBuf[index and 1]^,count[index and 1],count[index and 1],@Overlapped);
   GetOverlappedResult(Fi,Overlapped,count[index and 1],true);
 
while count[index and 1]<>0 do
begin
   Size^:=Size^ -  count[index and 1];
   inc(index);
//следующий запрос на чтение
   ResetEvent(Overlapped.hEvent);
   count[index and 1]:=BufSize;
   if Size^ < BufSize then count[index and 1]:=Size^;
   ReadFile(Fi,pBuf[index and 1]^,count[index and 1],count[index and 1],@Overlapped);
   dec(index);
{
    здесь любые ваши вычисления.
    pBuf[ (index and 1)]   - указатель на прочитанные данные.
    Count[ (index and 1)]  - размер прочитанных данных.
 
}
//ожидаем завершения чтения
   inc(index);
   GetOverlappedResult(Fi,Overlapped,count[index and 1],true);
end;
end;
Result:=not Result;
FreeMem(pBuf[0]);
FreeMem(pBuf[1]);
CloseHandle(Fi);
end;

procedure Tform1.Button1Click(Sender: TObject); 
var
  OverRead:TOverlapped;
 res:cardinal;
begin
  ZeroMemory(@OverRead,sizeof(OverRead));
  OverRead.hEvent := CreateEvent(nil,true,false,nil);
  if opendialog1.execute then
  res:= AsyncReadFile(opendialog1.filename,OverRead);
  memo1.lines.add(res??????); //не понимаю как вывести или делать cardinaltostring
  CloseHandle(OverRead.hEvent);
end;
end;
noveek вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение и запись в файл (С++) ura11_98 Помощь студентам 1 23.05.2016 19:13
Чтение и запись в файл (C++) lev_ Помощь студентам 1 11.12.2014 23:56
Чтение\запись в файл VirtualAngel Помощь студентам 2 12.02.2011 12:54
Чтение и запись из/в файл Pirotexnik Общие вопросы C/C++ 7 28.01.2011 16:54
Чтение и запись в файл deagle05 Общие вопросы C/C++ 3 22.12.2009 00:11