![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
[Delphi 2006, Access] Загрузка файла в базу данных [Access MDB]
Дмитрий © (2009-02-20 08:55:00)Добрый день.
Такая проблема: загружаю файл в базу данных, необходимо отслеживать ход выполнения, поэтому пишу кусками, работа с потоками выглядит так:
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 занимает практически столько же времени, а отобразить его бегунком уже нельзя. Может, я в принципе использую неправильный подход и надо сделать все по-другому? Тогда как?
Сергей М. (2009-02-22 17:55:00) [1]function TMyFileStream.Read(var Buffer; Count: Longint): Longint; //override
begin
Result := inherited Read(Buffer, Min(Count, BSize)); // вуаля !!
end;
Сергей М. (2009-02-22 17:47:00) [2]
> необходимо отслеживать ход выполнения
Существует изящный способ реализации подобных задач - использование своего наследника TFileStream с перекрытым методом Read.
Сергей М. (2009-02-22 17:31:00) [3]
> Дмитрий
aqBase - это кто, ADOQuery ?
А зачем же делать селективный запрос и возвращать навигируемый НД (подозреваю что CursorLocation у него = clUseClient, т.е. сразу в лес с мылом и веревкой), если все что требуется от метода TFDM.AddFile - это добавитьзапись ?
Amoeba (2009-02-20 16:59:00) [4]
> Дмитрий (20.02.09 12:00) [4]
А кто за тебя будет вызывать Free у blob и fs? Пушкин? Да здравствуют утечки памяти?
Sergey13 (2009-02-20 13:38:00) [5]> [6] Дмитрий (20.02.09 12:28)
> Там будут создаваться новые базы при исчерпании лимита.
Кошмар! Потом будешь делать отдельную БД для навигации по заполненным? Это ТЗ тоже такое?
Дмитрий (2009-02-20 12:28:00) [6]Там будут создаваться новые базы при исчерпании лимита. Вообще, большие файлы - редкость, но могут быть, может, один на базу.
Sergey13 (2009-02-20 12:01:00) [7]> [2] Дмитрий (20.02.09 11:12)
> а когда под сотню
И кстати, а сколько таких файлов ты собираешься записать? У аксеса вроде ограничение на размер файла вроде есть 2 гига. Хотя могу и ошибаться, но что то тут про это говорили.
Например тут
http://www.delphimaster.ru/cgi-bin/forum.pl?n=1&id=1235022074
Дмитрий (2009-02-20 12:00:00) [8]На ТЗ тоже забить?
Есть еще одна проблема. На методе 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 11:37:00) [9]> [2] Дмитрий (20.02.09 11:12)
ИМХО все исключительно.
Делать такое нужно тогда, когда пользователь должен по ходу процесса принимать решения по его продолжению/отмене, направлять процесс изменяя какие то параметры. Я так понимаю, что ничего такого у тебя не предполагается. Это все равно что предлагать гонщикам Ф1 во время гонки выходить из машины на каждом круге и отмечаться в ведомости, что бы узнать кто за кем едет.
Повесь анимашку для развлечения юзера и забей на это.
Дмитрий (2009-02-20 11:12:00) [10]Когда файлик на пару мегобайт - смысла нет, а когда под сотню, то процесс занимает уже продолжительное время и показывать пользователю висячее окно не гоже.
Sergey13 (2009-02-20 09:32:00) [11]> [0] Дмитрий (20.02.09 08:55)
> необходимо отслеживать ход выполнения
А смысл?