Форум: "Начинающим";
Текущий архив: 2006.10.15;
Скачать: [xml.tar.bz2];
ВнизDelphi IO работает только с файлами до 2 Гб? Найти похожие ветки
← →
Piter © (2006-09-30 14:23) [0]Сидел, ломал голову тут почему моя программа не работает. Судя по всему, все эти reset / rewrite / blockread / blockwrite работают только с файлами до ~2 Гб (видимо, как раз "положительный" диапазон integer). Так ли это?
Не ожидал от borland такой подставы...
← →
Джо © (2006-09-30 14:30) [1]> Так ли это?
Тут проблема не в перечисленных процедурах, а в Seek (там позиция задается 32-битным параметром Longint) и вообще в позиционировании.
← →
oxffff © (2006-09-30 14:40) [2]Longint - signed 32-bit.
Не ожидал от borland такой подставы...?
Переходите на ASM.
А лучше на маш. коды 237,176 (ZX Spectrum Команда LDIR)
← →
Джо © (2006-09-30 14:43) [3]> [2] oxffff © (30.09.06 14:40)
> Переходите на ASM.
Зачем так строго? Достаточно использовать Win32 API с его SetFilePointer.
← →
Джо © (2006-09-30 14:43) [4]Да, и при чем тут ASM вообще?
← →
oxffff © (2006-09-30 14:46) [5]Открывайте Platform SDK: File Management Functions.
CreateFile, ReadFileEx, WriteFileEx, CloseHandle
Да Borland еще не написала своих оберток под OVERLAPPED IO, Memory Mapped Files и т.д. и т.п.
А нужно ли это.
← →
Eraser © (2006-09-30 14:48) [6]однако ж в TMemoryStream есть вот такая версия Seek.
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual;
работает или нет - не проверял.
← →
oxffff © (2006-09-30 14:50) [7]Для меня лично это кажется странным.
>Piter
>Не ожидал от borland такой подставы...
push ebx
push 0
....
push eax
call [CreateFileA]
Тут никаких притензий к Borland
← →
Джо © (2006-09-30 15:00) [8]> [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.
← →
guav © (2006-09-30 15:07) [9]> однако ж в TMemoryStream есть вот такая версия Seek.
> function Seek(const Offset: Int64; Origin: TSeekOrigin):
> Int64; overload; virtual;
Думаю речь таки идёт о TFileStream . Или вы уже адресуете более 4 ГБ в 32 разрядном коде ? ;-)
Судя по исходникам, должна работать
← →
Piter © (2006-09-30 15:14) [10]Джо © (30.09.06 14:30) [1]
Тут проблема не в перечисленных процедурах, а в Seek (там позиция задается 32-битным параметром Longint) и вообще в позиционировании.
ага, наверное. Я не разбирался, у меня проблема была в том, что сделав Reset на таком большом файле EOF сразу показывала true.
← →
Eraser © (2006-09-30 15:32) [11]> [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 17:28) [12]Eraser © (30.09.06 15:32) [11]
да это теперь очевидно... Просто странно, что borland лоханулись в этом вопросе...
← →
Anatoly Podgoretsky © (2006-09-30 17:30) [13]reset вообще не работает с размером.
А rewrite работает с размером 0 байт.
Вот blockread / blockwrite уже работают с байтиками, но и там нет размера, есть ограничение на одновременно прочитаное количество байтиков, так и Микрософт не в состоянии читать свыше 2 гб за раз, ограничение ОС.
Мне кажется, что автор пытается обойти это ограничение для Win32
← →
Джо © (2006-09-30 17:36) [14]> [13] Anatoly Podgoretsky © (30.09.06 17:30)
> Вот blockread / blockwrite уже работают с байтиками, но
> и там нет размера, есть ограничение на одновременно прочитаное
> количество байтиков, так и Микрософт не в состоянии читать
> свыше 2 гб за раз, ограничение ОС.
Дело не в том, а в том, что для file pointer в делфийском Seek предусмотрен Longint, а не Int64.
← →
Anatoly Podgoretsky © (2006-09-30 18:12) [15]Дело не в этом, ни одна из указаных функций не работает с размером файла и теоретически не имет ограничений. Другое дело, что BlockRead оставлен для совместимости со старыми программами, cушествует с 70 годов прошлого века, и нет никакого основания использовать его в новых, для этого предназначен TFileStream. Я бы понял если бы это использовалось для текстовых или не типизированых файлов, поскольку нет альтернативы, но для не типизированых файлов есть полноценная замена, а использовать старую - это себе вредить.
Про Seek в вопросе нет ни слова.
← →
Anatoly Podgoretsky © (2006-09-30 18:20) [16]Вот доказательство
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:22) [17]
> Не ожидал от borland такой подставы...
Подставу искать не там, есть более подходящие цели.
← →
Anatoly Podgoretsky © (2006-09-30 18:23) [18]Кстати у нас даже начинающие приводят код как неправильно сделано.
← →
oxffff © (2006-09-30 18:37) [19]> > [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:43) [20]oxffff © (30.09.06 18:37) [19]
Это точно, к вопросу отношения не имеет. Пожелание наверно. А если так, то FileStream
← →
jTommy (2006-09-30 20:42) [21]Провел небольшое исследование, и теперь ответственно заявляю: метод 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.
← →
Джо © (2006-09-30 21:01) [22]> [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.
← →
Джо © (2006-09-30 21:01) [23]Ну, лишние переменные убрать :)
← →
jTommy (2006-09-30 22:03) [24]
> Джо © (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.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.10.15;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.043 c