Форум: "Базы";
Текущий архив: 2010.02.21;
Скачать: [xml.tar.bz2];
Вниз[Delphi 2006, Access] Загрузка файла в базу данных Найти похожие ветки
← →
Дмитрий (2009-02-20 08:55) [0]Добрый день.
Такая проблема: загружаю файл в базу данных, необходимо отслеживать ход выполнения, поэтому пишу кусками, работа с потоками выглядит так:
Function CopyData(Source, Destination: TStream; Count: Int64): Int64;
Function Min(a: Int64; b: Integer): Integer;
Begin
if (a<0) or (b<a) then result:=b else result:=a;
End;
Var
BSize: Integer;
B: PChar;
BytesToRead,BytesRead: Integer;
Block : integer;
i : integer;
Begin
i:=0;
FPB.Properties.Min := 0;
block := Count div $F000;
FPB.Properties.Max := (block div 10) + 1;
Result:=0;
BSize:=Min(Count,$F000);
GetMem(B, BSize);
try
repeat
BytesToRead:=Min(Count,BSize);
BytesRead:=Source.Read(B^,BytesToRead);
Destination.Write(B^,BytesRead);
Inc(Result,BytesRead); Dec(Count,BytesRead);
inc(i);
if i mod 10 = 0 then FPB.Position := i/10;
Application.ProcessMessages;
until (BRead<BytesToRead) or (Count=0);
finally
FreeMem(B, BSize);
end;
End;
В основе - код, найденный на просторах рунета.
Процесс загрузки постепенно замедляется и с резвого бега в начале переходит к вялому ползанию в конце. Можно это как-то исправить, от чего оно зависит?
Кроме того, последующий вызов метода Post занимает практически столько же времени, а отобразить его бегунком уже нельзя. Может, я в принципе использую неправильный подход и надо сделать все по-другому? Тогда как?
← →
Sergey13 © (2009-02-20 09:32) [1]> [0] Дмитрий (20.02.09 08:55)
> необходимо отслеживать ход выполнения
А смысл?
← →
Дмитрий (2009-02-20 11:12) [2]Когда файлик на пару мегобайт - смысла нет, а когда под сотню, то процесс занимает уже продолжительное время и показывать пользователю висячее окно не гоже.
← →
Sergey13 © (2009-02-20 11:37) [3]> [2] Дмитрий (20.02.09 11:12)
ИМХО все исключительно.
Делать такое нужно тогда, когда пользователь должен по ходу процесса принимать решения по его продолжению/отмене, направлять процесс изменяя какие то параметры. Я так понимаю, что ничего такого у тебя не предполагается. Это все равно что предлагать гонщикам Ф1 во время гонки выходить из машины на каждом круге и отмечаться в ведомости, что бы узнать кто за кем едет.
Повесь анимашку для развлечения юзера и забей на это.
← →
Дмитрий (2009-02-20 12:00) [4]На ТЗ тоже забить?
Есть еще одна проблема. На методе Post прога начинает сильно отжирать память, на 50 метровый файл 500 оперативки. Там явно что-то не то, но что может быть?
Код еще одной функции:
function TFDM.AddFile(const Path : string): integer;
var
blob: TStream;
fs : TFileStream;
sMsg : string;
begin
with aqBase do begin
SQL.Text := "select * from FTABLE where ID = 0";
Active := true;
Append;
blob := CreateBlobStream(FieldByName("FILE"), bmWrite);
fs := TFileStream.Create(Path, fmOpenRead);
sMsg := CopytoField (fs, blob);// там вызывается CopyData
if sMsg <> "" then MessageBox (0, PChar(sMsg), "Ошибка", MB_OK + MB_ICONERROR);
FieldByName("NAME").AsString := ExtractFileName(Path);
Post;
result := FieldByName("ID").AsInteger;
Active := False;
end; // with
end;
← →
Sergey13 © (2009-02-20 12:01) [5]> [2] Дмитрий (20.02.09 11:12)
> а когда под сотню
И кстати, а сколько таких файлов ты собираешься записать? У аксеса вроде ограничение на размер файла вроде есть 2 гига. Хотя могу и ошибаться, но что то тут про это говорили.
Например тут
http://delphimaster.net/view/3-1235022074/
← →
Дмитрий (2009-02-20 12:28) [6]Там будут создаваться новые базы при исчерпании лимита. Вообще, большие файлы - редкость, но могут быть, может, один на базу.
← →
Sergey13 © (2009-02-20 13:38) [7]> [6] Дмитрий (20.02.09 12:28)
> Там будут создаваться новые базы при исчерпании лимита.
Кошмар! Потом будешь делать отдельную БД для навигации по заполненным? Это ТЗ тоже такое?
← →
Amoeba © (2009-02-20 16:59) [8]
> Дмитрий (20.02.09 12:00) [4]
А кто за тебя будет вызывать Free у blob и fs? Пушкин? Да здравствуют утечки памяти?
← →
Сергей М. © (2009-02-22 17:31) [9]
> Дмитрий
aqBase - это кто, ADOQuery ?
А зачем же делать селективный запрос и возвращать навигируемый НД (подозреваю что CursorLocation у него = clUseClient, т.е. сразу в лес с мылом и веревкой), если все что требуется от метода TFDM.AddFile - это добавить запись ?
← →
Сергей М. © (2009-02-22 17:47) [10]
> необходимо отслеживать ход выполнения
Существует изящный способ реализации подобных задач - использование своего наследника TFileStream с перекрытым методом Read.
← →
Сергей М. © (2009-02-22 17:55) [11]function TMyFileStream.Read(var Buffer; Count: Longint): Longint; //override
begin
Result := inherited Read(Buffer, Min(Count, BSize)); // вуаля !!
end;
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2010.02.21;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c