Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 2003.01.27;
Скачать: [xml.tar.bz2];

Вниз

Скорость работы AssignFile();   Найти похожие ветки 

 
3223(jab)   (2002-11-11 22:35) [0]

Помогите разобраться с AssignFile();
Вопрос в скорости работы с диском, а именно мне нужно из одного файла переписать данный в другой. Для этого я работаю в цикле:
var
i:Integer;
buf:Byte;
f1,f2:File;
begin
AssignFile(f1,"c:\1.dat");AssignFile(f2,"c:\2.dat");
Reset(f1,1);ReWrite(f2,1); //создаю второй файл и открываю на
//запись
for i:=0 to 120 do begin
seek(f1,0+i);seek(f2,51+i);
BlockRead(f1,buf,1);BlockWrite(f2,buf,1);
//Не имеет значения адресация
end;
CloseFile(f1);CloseFile(f2);
end;
Проблема в том, что если у меня файл в 500Кб и выше у меня очень медленно это происходит. Я так понял он каждый раз обращается к файля, чтоб считать байт, потом переключается на другой файл и т.д. что очень тормозит! Как мне считать из файла кусок в 120(к примеру) килобайт, а потом его записать в другой файл???


 
Snap   (2002-11-11 22:38) [1]

Тупой вопрос!
Делай больше буфер и пиши в blockread blockwrite последний параметр не 1 , а 120. Но тогда ещё нужна проверка на то что осталось ли нескопированное место. Но это уж сам сделай


 
Dr_Mike   (2002-11-11 22:51) [2]

А в винде есть еще такие классные штучки, как отображение файлов и т.д. - открой хелп, и почитай, что расскажет по поводу "File mapping"...


 
3223(jab)   (2002-11-11 22:51) [3]

Знаю что тупой вопрос, но реализовать не получается по непонятной причине...
Если можно примерчик!? Не могу понять как оно работает.


 
Snap   (2002-11-11 22:57) [4]

var
i:Integer;
buf:array [0..101] of Byte;
f1,f2:File;
readed,all:longint;
begin
AssignFile(f1,"c:\1.dat");AssignFile(f2,"c:\2.dat");
Reset(f1,1);ReWrite(f2,1); //создаю второй файл и открываю на
//запись
all:=filesize(f1);
readed:=0;
repeat
if readed+102>all then
begin
BlockRead(f1,buf,all-readed);BlockWrite(f2,buf,all-readed);
readed:=all;
end else begin
BlockRead(f1,buf,102);BlockWrite(f2,buf,102);
inc(readed,102);
end;
until readed<>all;
//Не имеет значения адресация
CloseFile(f1);CloseFile(f2);
end;


 
3223(jab)   (2002-11-11 22:59) [5]

Может кто знает ещё какой способ считать с 50 по n байты и записать их в другой файл, только с максимальным быстродействием.
Позарез нужно, а то пока обработаю файл в 106 Мб можно приготовить покушать и принять ванну.


 
Dm9   (2002-11-11 23:58) [6]

Сам ничего, кроме 1-го метода не использовал, так что разбирайся сам.

From FAQ:

Копирование файлов


Копирование методом TurboPascal


Type
TCallBack=procedure (Position,Size:Longint); {Для индикации процесса копирования}
procedure FastFileCopy(Const InfileName, OutFileName: String; CallBack: TCallBack);
Const BufSize = 3*4*4096; { 48Kbytes дает прекрасный результат }
Type
PBuffer = ^TBuffer;
TBuffer = array [1..BufSize] of Byte;
var
Size : integer;
Buffer : PBuffer;
infile, outfile : File;
SizeDone,SizeFile: Longint;
begin
if (InFileName <> OutFileName) then
begin
buffer := Nil;
AssignFile(infile, InFileName);
System.Reset(infile, 1);
try
SizeFile := FileSize(infile);
AssignFile(outfile, OutFileName);
System.Rewrite(outfile, 1);
try
SizeDone := 0; New(Buffer);
repeat
BlockRead(infile, Buffer^, BufSize, Size);
Inc(SizeDone, Size);
CallBack(SizeDone, SizeFile);
BlockWrite(outfile,Buffer^, Size)
until Size < BufSize;
FileSetDate(TFileRec(outfile).Handle,
FileGetDate(TFileRec(infile).Handle));
finally
if Buffer <> Nil then Dispose(Buffer);
System.close(outfile)
end;
finally
System.close(infile);
end;
end else
Raise EInOutError.Create("File cannot be copied into itself");
end;


Копирование методом потока


Procedure FileCopy(Const SourceFileName, TargetFileName: String);
Var
S,T : TFileStream;
Begin
S := TFileStream.Create(sourcefilename, fmOpenRead );
try
T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate);
try
T.CopyFrom(S, S.Size ) ;
FileSetDate(T.Handle, FileGetDate(S.Handle));
finally
T.Free;
end;
finally
S.Free;
end;
end;


Копирование методом LZExpand


uses LZExpand;
procedure CopyFile(FromFileName, ToFileName : string);
var
FromFile, ToFile: File;
begin
AssignFile(FromFile, FromFileName);
AssignFile(ToFile, ToFileName);
Reset(FromFile);
try
Rewrite(ToFile);
try
if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle)<0 then
raise Exception.Create("Error using LZCopy")
finally
CloseFile(ToFile);
end;
finally
CloseFile(FromFile);
end;
end;


Копирование методами Windows


uses ShellApi; // !!! важно
function WindowsCopyFile(FromFile, ToDir : string) : boolean;
var F : TShFileOpStruct;
begin
F.Wnd := 0; F.wFunc := FO_COPY;
FromFile:=FromFile+#0; F.pFrom:=pchar(FromFile);
ToDir:=ToDir+#0; F.pTo:=pchar(ToDir);
F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION;
result:=ShFileOperation(F) = 0;
end;
// пример копирования
procedure TForm1.Button1Click(Sender: TObject);
begin
if not WindowsCopyFile("C:\UTIL\ARJ.EXE", GetCurrentDir) then
ShowMessage("Copy Failed");
end;


 
Dm9   (2002-11-11 23:59) [7]

Надеюсь, поможет


 
3223(jab)   (2002-11-12 00:16) [8]

тоже надеюсь


 
3223(jab)   (2002-11-12 00:18) [9]

Dm9 Спасибо!


 
3223(jab)   (2002-11-12 00:22) [10]

Dm9, просто мне важно было не только файл целиком копировать, но и копировать пол файла или вообще избирательно например с 0x0A по 0xFA1 потом ещё какой нибуть кусок(файл по кускам) С AssignFile(); понятно как, но медленно у меня получалось... Ладно испробую все выше перечисленные способы.
Спасибо всем!


 
apay   (2002-11-12 00:53) [11]

2 Dm9
никак не пойму зачем нужно следующее:

FromFile:=FromFile+#0;

вроде бы не требо чтобы строка кончалась двойным нулем Ж)


 
Dm9   (2002-11-12 02:34) [12]

apay © (12.11.02 00:53)
Честно говоря, не знаю. Я пользовался только первым методом - как-то не было необходимости в быстром копировании больших файлов.
FromFile:=FromFile+#0; - действительно странно, так как PChar, по идее, добавляет ноль в конец. А не пробовал удалить строки с прибавлением нуля? У меня просто Delphi не работает, а переустанавливать сейчас не охота.

Кстати, никто не знает, что это такое: "Read error on "C:\Program Files\Borland\Delphi6\Lib\SysUtils.dcu""? Файл, существует. Поврежён, может? Или это глюк Delphi?


 
3223(jab)   (2002-11-14 10:48) [13]

Самый путёвый способ(на мой взгляд) через массив!
var
buf:Array[0..2048] of Byte;
Но как можно по ходу программы изменя размерность массива т.е.
buf:Array[0..2048] of Byte; изменять [0..2048] этот кусок в нужных мне приделах, например мне нужно [0..5] или [0..10] или любой другой, а не из начала [0..100000] на все случаи жизни так сказать!


 
Romeo   (2002-11-15 11:33) [14]

Что бы добиться максимальной скорости нужно использовать прямой асинхронный доступ к устройству.

Могу дать исходник на Visual C

Надо? пиши tiraspol_romeo@rambler.ru


 
apay   (2002-11-16 01:18) [15]

если читать из файла данные подряд, т.е. не перемещать все время указатель ф-ей SetFilePointer (seek по-простому), то вроде достаточно при открытии файла ф-ей CreateFile поставить FILE_FLAG_SEQUENTIAL_SCAN и можно не делать большой буфер для чтения


 
3223(jab)   (2002-11-16 15:16) [16]

В общем, то всё понятно стало.
При переписывании не возникает проблем! Всем спасибо.
Через буфер в 2048 байт работает очень быстро! Даже превзошло мои ожидания!
_______________________________



Страницы: 1 вся ветка

Форум: "Система";
Текущий архив: 2003.01.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.011 c
1-86737
Ikvasn
2003-01-16 14:40
2003.01.27
Поиск в TRichEdit


1-86839
error 2k
2003-01-18 23:32
2003.01.27
Пауза в программе


1-86812
simka
2003-01-19 00:37
2003.01.27
вопрос по memo


3-86700
dolmat
2003-01-09 11:23
2003.01.27
Нужно создать SQL по части поля


6-87004
Eugene_Popov
2002-11-30 10:59
2003.01.27
найти машину в сети





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский