Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Delphi IO работает только с файлами до 2 Гб?


Страницы:   1 2

Piter ©   (2006-09-30 14:23:00) 

Сидел, ломал голову тут почему моя программа не работает. Судя по всему, все эти reset / rewrite / blockread / blockwrite работают только с файлами до ~2 Гб (видимо, как раз "положительный" диапазон integer). Так ли это?

Не ожидал от borland такой подставы...


jTommy   (2006-09-30 22:03:00) [1]


> Джо ©   (30.09.06 21:01) [22]

> Fs.Seek(1,soFromEnd);

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

Но если вызвать так:

SeekResult:=Fs.Seek(1,soFromEnd);

То результат в SeekResult будет неправильный. Это не нормально.

И все-таки, если я пытаюсь установить указатель от начала файла:

fpos:=любое смещение;
fs.Seek(fpos, soFromBeginning);
WriteLn(fs.Position);

за пределом в 2.1Гб fs.Position возвратит размер_файла-1, а за пределом 4.2Гб - значение около 250-375Мб.

Более того, если скомпилировать с проверкой границ(Range Checking) на вызове fs.Seek случиться исключение ERangeError.


Джо   (2006-09-30 21:01:00) [2]

Ну, лишние переменные убрать :)


Джо   (2006-09-30 21:01:00) [3]

> [21] jTommy   (30.09.06 20:42)

Неправильно тестируем, товарищ :)Попробуйте следующим образом:

program Project2;

{$APPTYPE CONSOLE}

uses
 SysUtils,
 Classes;

var
 Fs: TFileStream;
 SeekResult: Int64;
 Position: Int64;
begin
 // Файл ~4 Гб
 Fs := TFileStream.Create('J:\pub\video\hdtv\The.Shawshank.R.1280x720.HDTVRip.XviD.AC3-5.1_Eng+Rus.(www.rusdivx.ee).cd1.avi',fmOpenRead);
 try
   Position := 1;
   Fs.Seek(1,soFromEnd);
   WriteLn (Fs.Position);
   ReadLn;

 finally
   Fs.Free
 end;

end.


jTommy   (2006-09-30 20:42:00) [4]

Провел небольшое исследование, и теперь ответственно заявляю: метод Seek класса TFileStream неправильно работает с файлами больше 2Гб :(.

Еще проверял копирование - естественно с этим все в порядке, копирует один в один.
Программа пробует установить указатель на позицию размер_файла-8мб.

Код программы:

program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils, Classes;

Const
 szBuffer = 8388608; // 8mb

Var
 fsIN: TFileStream;
 fpos: int64;

begin
 fsIN:=TFileStream.Create(ParamStr(1), fmOpenRead);

 fpos:=fsIN.Seek(fsIN.Size-szBuffer, soFromBeginning);
 WriteLn('Need position: ',fsIN.Size-szBuffer,' Seek result: ',fpos);

 fsIN.Free;
end.


Результаты работы (в байтах):

Need position: 519.129.088 Seek result: 519.129.088
Need position: 4.282.613.760 Seek result: -1
Need position: 4.653.842.432 Seek result: 358.875.136


P.S.: файловая система естественно - NTFS.


Anatoly Podgoretsky   (2006-09-30 18:43:00) [5]

oxffff ©   (30.09.06 18:37) [19]
Это точно, к вопросу отношения не имеет. Пожелание наверно. А если так, то FileStream


oxffff   (2006-09-30 18:37:00) [6]

> > [5] oxffff ©   (30.09.06 14:46)
> > Открывайте Platform SDK: File Management Functions.
> >
> > CreateFile, ReadFileEx, WriteFileEx, CloseHandle
>
> Этим-то как раз абсолютно фиолетов размер файла. Точно так
> же, как и AssignFile,Reset, CloseFile.


Что то я тебя не понял.


Anatoly Podgoretsky   (2006-09-30 18:23:00) [7]

Кстати у нас даже начинающие приводят код как неправильно сделано.


Anatoly Podgoretsky   (2006-09-30 18:22:00) [8]


> Не ожидал от borland такой подставы...

Подставу искать не там, есть более подходящие цели.


Anatoly Podgoretsky   (2006-09-30 18:20:00) [9]

Вот доказательство
unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

const
 Chunk = 1000000;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Label1: TLabel;
   Label2: TLabel;
   procedure Button1Click(Sender: TObject);
 end;

 TAr = Array [1..Chunk] of byte;

var
 Form1: TForm1;
 f: file of Byte;
 Ar: TAr;
 Tr: Integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 I: Integer;
 ReadBytes: Int64;
begin
 AssignFile(f, 'c:\Temp\1');
 Reset(f);
 ReadBytes := 0;
 while True do begin
   BlockRead(f, ar, Chunk, Tr);
   ReadBytes := ReadBytes + Tr;
   Label2.Caption := FormatFloat(',0', ReadBytes);
   Application.ProcessMessages;
   if ReadBytes < Chunk then Exit;
 end;
end;

end.


Label2.Caption := 5 868 773 384
Как видим это больше 2 гб и даже больше 4 гб!!!

Борланд невинно оболган


Anatoly Podgoretsky   (2006-09-30 18:12:00) [10]

Дело не в этом, ни одна из указаных функций не работает с размером файла и теоретически не имет ограничений. Другое дело, что BlockRead оставлен для совместимости со старыми программами, cушествует с 70 годов прошлого века, и нет никакого основания использовать его в новых, для этого предназначен TFileStream. Я бы понял если бы это использовалось для текстовых или не типизированых файлов, поскольку нет альтернативы, но для не типизированых файлов есть полноценная замена, а использовать старую - это себе вредить.
Про Seek в вопросе нет ни слова.


Джо   (2006-09-30 17:36:00) [11]

> [13] Anatoly Podgoretsky ©   (30.09.06 17:30)
> Вот blockread / blockwrite уже работают с байтиками, но
> и там нет размера, есть ограничение на одновременно прочитаное
> количество байтиков, так и Микрософт не в состоянии читать
> свыше 2 гб за раз, ограничение ОС.

Дело не в том, а в том, что для file pointer в делфийском Seek предусмотрен Longint, а не Int64.


Anatoly Podgoretsky   (2006-09-30 17:30:00) [12]

reset вообще не работает с размером.
А rewrite работает с размером 0 байт.
Вот blockread / blockwrite уже работают с байтиками, но и там нет размера, есть ограничение на одновременно прочитаное количество байтиков, так и Микрософт не в состоянии читать свыше 2 гб за раз, ограничение ОС.
Мне кажется, что автор пытается обойти это ограничение для Win32


Piter   (2006-09-30 17:28:00) [13]

Eraser ©   (30.09.06 15:32) [11]

да это теперь очевидно... Просто странно, что borland лоханулись в этом вопросе...


Eraser   (2006-09-30 15:32:00) [14]

> [9] guav ©   (30.09.06 15:07)

ну да, я имел ввиду именно TFileStream :)

> [10] Piter ©   (30.09.06 15:14)

тогда думаю стОит отказаться от консольных функций и использовать либо TFileStream, либо функции типа FileOpen, FileRead и т.п. на который и построен TFileStream, лобо вообще использовать Win API напрямую.


Piter   (2006-09-30 15:14:00) [15]

Джо ©   (30.09.06 14:30) [1]
Тут проблема не в перечисленных процедурах, а в Seek (там позиция задается 32-битным параметром Longint) и вообще в позиционировании.


ага, наверное. Я не разбирался, у меня проблема была в том, что сделав Reset на таком большом файле EOF сразу показывала true.


guav   (2006-09-30 15:07:00) [16]

> однако ж в TMemoryStream есть вот такая версия Seek.
> function Seek(const Offset: Int64; Origin: TSeekOrigin):
> Int64; overload; virtual;

Думаю речь таки идёт о T FileStream . Или вы уже адресуете более 4 ГБ в 32 разрядном коде ? ;-)
Судя по исходникам, должна работать


Джо   (2006-09-30 15:00:00) [17]

> [6] Eraser ©   (30.09.06 14:48)
> однако ж в TMemoryStream есть вот такая версия Seek.
> function Seek(const Offset: Int64; Origin: TSeekOrigin):
> Int64; overload; virtual;
> работает или нет - не проверял.

Работает.


> [5] oxffff ©   (30.09.06 14:46)
> Открывайте Platform SDK: File Management Functions.
>
> CreateFile, ReadFileEx, WriteFileEx, CloseHandle

Этим-то как раз абсолютно фиолетов размер файла. Точно так же, как и AssignFile,Reset, CloseFile.


oxffff   (2006-09-30 14:50:00) [18]

Для меня лично это кажется странным.

>Piter
>Не ожидал от borland такой подставы...

push ebx
push 0
....
push eax
call [CreateFileA]

Тут никаких притензий к Borland


Eraser   (2006-09-30 14:48:00) [19]

однако ж в TMemoryStream есть вот такая версия Seek.
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual;
работает или нет - не проверял.


oxffff   (2006-09-30 14:46:00) [20]

Открывайте Platform SDK: File Management Functions.

CreateFile, ReadFileEx, WriteFileEx, CloseHandle

Да Borland еще не написала своих оберток под OVERLAPPED IO, Memory Mapped Files и т.д. и т.п.

А нужно ли это.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо