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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.01.2023, 20:08   #1
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию Не работает TFileStream.Seek при больших файлах

Пытаюсь использовать Seek при чтении какой-то строки в большом файле ( 26.5 Гб - 327 258 385 строк по 81 символу).
Не работает, когда счетчик байтов более High(Integer), хотя использую Int64.
Код:
procedure TForm1.Button23Click(Sender: TObject);
const LEN = 81;
var FS: TFileStream;
   buf:array[0..LEN-1] of Char;
   nb,k:Int64;  // т.к. длинный файл
   i,n:Integer;
begin
 n:=Memo1.Lines.Count;
 if n=0 then Exit;
 FS := TFileStream.Create(DIRDAT+Trim(Edit1.Text)+'.txt', fmOpenRead);
 try
  for i:=0 to n-1 do
   begin
    k:=StrToIntDef(Memo1.Lines.Strings[i],0);  // в Memo1 ввожу нужные номера строк
    nb:=k*LEN;   // чтобы Int64
    Memo3.Lines.Add(IntToStr(FS.Seek(nb,soFromBeginning))); // перемещение и вывод позиции
    Memo4.Lines.Add(IntToStr(FS.Position));  // вывод позиции
    FS.Read(buf,LEN);
    Memo2.Lines.Add(buf);  // вывод самой строки 
   end;
 finally
   FS.Free;
 end;
end;
Функция Seek - именно с Int64 - см.рис "seek"
Если просто строки по порядку , без Seek - то работает, но очень долго, проверял.
Код:
// ...
try
   k:=FS.Size div 81;
   FS.Seek(0,soFromBeginning);
   for i:=0 to k-1 do
    begin
     FS.Read(buf,81);  // вот так работает до конца длинного файла
// ...
Как же заставить делать seek на большие значения?

PS Это в Delphi 7, кстати и в Lazarus v1.6.4 - то же самое.
Изображения
Тип файла: png seek.PNG (7.3 Кб, 26 просмотров)
Тип файла: png Memo4.png (12.3 Кб, 0 просмотров)

Последний раз редактировалось type_Oleg; 11.01.2023 в 20:15.
type_Oleg вне форума Ответить с цитированием
Старый 11.01.2023, 20:39   #2
jillitil
Форумчанин
 
Аватар для jillitil
 
Регистрация: 17.10.2018
Сообщений: 184
По умолчанию

Чем хорош дельфи? Тем что по Ф7-Ф8 можно пройти пошагово, просмотреть значения переменных, и получить ошибку в читаемом для человека виде.
Код:
Generic integer types for 32-bit implementations of Delphi  
Type	Range	Format
Integer	-2147483648..2147483647	signed 32-bit

Fundamental integer types  
Type	Range	Format
Longint	-2147483648..2147483647	signed 32-bit
Int64	-2^63..2^63-1	signed 64-bit
Изображения
Тип файла: jpg screenshot.1.jpg (81.4 Кб, 27 просмотров)
jillitil вне форума Ответить с цитированием
Старый 11.01.2023, 20:52   #3
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию

Цитата:
Сообщение от jillitil Посмотреть сообщение
пройти пошагово, просмотреть значения переменных,
nb - нормально все. Вот - на рис при вводе 100 000 000

Я нашёл выход-
Код:
// ...
 Memo3.Lines.Add(IntToStr(BigSeek(FS,nb)));
// ... функция BigSeek:
function BigSeek(F:TFileStream;n:Int64):Int64;
var k,m,i:Integer;
    dn:Int64;
begin
 dn:=n-F.Position;
 if dn<MaxInt // 2147483647
  then Result:=F.Seek(dn,soFromCurrent) else
   begin
    k:=dn div MaxInt;
    for i:=1 to k do F.Seek(MaxInt,soFromCurrent);
    m:=dn mod MaxInt;
    Result:=F.Seek(m,soFromCurrent);
   end;
end;
Так работает. Может, кто более изящный способ найдет.
Изображения
Тип файла: png nb.PNG (6.9 Кб, 26 просмотров)
type_Oleg вне форума Ответить с цитированием
Старый 13.01.2023, 10:06   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

В коде из 1 сообщения вместо "soFromBeginning" использовать "SoBeginning" в строке:
Код:
Memo3.Lines.Add(IntToStr(FS.Seek(nb,soFromBeginning)));
Чтобы использовалась 64битная версия Seek вместо 32битной.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 13.01.2023, 11:20   #5
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
вместо "soFromBeginning" использовать "SoBeginning"
Вот спасибо, помогло.
type_Oleg вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Замена Seek fedorova-nusa Помощь студентам 16 24.12.2014 09:37
Не работает поиск записи методом seek. zakat2 Microsoft Office Access 5 08.08.2014 12:51
Lazarus. TProcess. Cannot seek on pipe Stilet Lazarus, Free Pascal, CodeTyphon 2 27.12.2012 23:28
seek & textfile dukales Помощь студентам 3 06.09.2011 18:17
Быстрый поиск в больших текстовых файлах RIO Общие вопросы Delphi 6 29.04.2011 15:46