Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.02.21;
Скачать: CL | DM;

Вниз

[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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.019 c
11-1174919254
ElectriC
2007-03-26 18:27
2010.02.21
Горизонтальная полоса прокрутки в ListBox


2-1261143805
TStas
2009-12-18 16:43
2010.02.21
Ошибка создания MDI формы


2-1261080452
TComponent
2009-12-17 23:07
2010.02.21
Устойчивый фокус на TreeView


2-1261068749
Б
2009-12-17 19:52
2010.02.21
Как установить размеры клиентской части окна?


2-1261124358
Burger
2009-12-18 11:19
2010.02.21
Удаление экземпляра объекта