Форум: "Основная";
Текущий архив: 2002.06.20;
Скачать: [xml.tar.bz2];
ВнизКак обращаться к буферу после считывания FileRead (SysUtils) Найти похожие ветки
← →
Novarm (2002-06-09 18:26) [0]Возникла проблема. Надо открывать большие файлы (WAV) для обработки. С помощью Write, Read (System) очень долго и постоянно глючит.
Открываю FileRead (FileHandle:integer; var Buffer; Count:integer)
Вроде все работает, но почему-то все значения Buffer[0..Count] равны 0. Уже пробовал представлять Buffer динамическим массивом:
Buffer: array of integer; и, как в стандартном примере из Help:
Buffer: PChar;
Вставлял код из примера без изменений - тот же эффект!
С уважением,
Станислав Руев
p.s. Примеры программ Delphi: http://www.novarm.com
← →
Novarm (2002-06-09 23:25) [1]Сегодня весь день продолбался!!!
Прогнал процесс пошагово. Инициализируется и динамический массив и PChar нормально, а после запуска FileRead длина Buffer обнуляется и при прямом обращении выдает Read of address 00345182x и в таком стиле. А при использовании обработки исключений просто оставляет массив как есть с нулями!
Вот так!
← →
SPeller (2002-06-09 23:48) [2]Ты бы хоть код свой привёл.....
← →
Novarm (2002-06-10 00:02) [3]Уно моменто!
При чтении более 1024 FileRead возвращает -1, поэтому я разбил на участки по 200.
procedure TWaveData.LoadFromFile;
var i,j,ms:integer;
buf:array of integer;
Buffer:array of byte;
FileHandle,iRead,ReadCount:integer;
FileLength:Int64;
begin
//Обнуление
freq:=0;
bits:=0;
chan:=0;
setlength (data1,0);
setlength (data2,0);
if (CurrentChan<1)or(CurrentChan>2) then
CurrentChan:=1;
//Чтение из файла
FileHandle := FileOpen(FileName, fmOpenRead);
FileLength := FileSeek(FileHandle,0,2);
ReadCount:=trunc(FileLength/200);
setlength (buf,200);
buf:=AllocMem(200); //Для понту
FileSeek(FileHandle,0,0);
for i:=0 to ReadCount-1 do
begin
iRead:=FileRead (FileHandle,buf,200);
setlength (Buffer,length(Buffer)+iRead);
for j:=0 to iRead-1 do
Buffer[high(Buffer)-iRead+j]:=Integer(buf[j]);
end;
setlength (buf,0);
FileClose (FileHandle);
end;
← →
Almaz (2002-06-10 02:01) [4]В случае обработки больших файлов, способ, который ты используешь далеко не оптимален. Я бы рекомендовал использовать проецирование файлов в память - этим ты убережешь себя и систему от лишней работы :). Приведенный ниже код показывает, как получить доступ к файлу, как к массиву байтов:
type
TBuffer = array [0..$7FFFFFFE] of Byte;
PBuffer = ^TBuffer;
procedure LoadFromFile;
var
Buffer: PBuffer;
FileHandle: Integer;
MapHandle: Integer;
FileName: String;
FSizeLow, FSizeHigh: Integer;
begin
FileName := ...
FileHandle := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ , nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
FSizeLow := GetFileSize(FileHandle, @FSizeHigh);
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READWRITE, FSizeHigh, FSizeLow, nil);
Buffer := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
//... работаем с массивом
// Buffer[122003] := 245;
// Buffer[13] := 243;
UnmapViewOfFile(Buffer);
CloseHandle(MapHandle);
CloseHandle(FileHandle);
end;
Удачи.
← →
cyborg (2002-06-10 08:58) [5]FileLength нужно Integer
А вообще лучше не заниматься мудистикой, а использовать паскалевские BlockRead и BlockWrite и никаких хендлов не нужно.
Type
FRecord = record
P : Pointer;
Size : Integer;
End;
Var
F : File;
Data : FRecord;
Begin
AssignFile(F,"file.wav");
ResetFile(f,1);
Data.Size:=FileSize(F);
GetMem(Data.P,Data.Size);
BlockRead(F,Data.P^,Data.Size);
FreeMem(Data.P,Data.Size);
CloseFile(F);
End;
← →
SPeller (2002-06-10 09:30) [6]УЕсли важна скорость работы, то используй ВинАПИ.
← →
Anatoly Podgoretsky (2002-06-10 09:42) [7]Странно это
setlength (buf,200);
buf:=AllocMem(200); //Для понту
Наверно точно для понту, а приведенный код даже и рассматривать нет смысла, очено много неопределенных вещей, непонятно для чего приведенных в коде
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.06.20;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.007 c