Карта0
Карта1
Карта2
Карта3
Карта4
Карта5
Карта6
Карта7
Карта8
Карта9
Карта10
Карта11
Карта12
Карта13
Карта14
Карта15
Карта16
Карта17
Карта18
Карта19
Карта20
Карта21
Карта22
Карта23
Карта24
Карта25
Карта26
Карта27
Карта28
Карта29
Карта30
Карта31
Карта32
Карта33
Карта34
Карта35
Карта36
Карта37
Карта38
Карта39


Наш форум » Железо и софт. Вопросы и ответы. » Программирование » Delphi - Need help

Ответ
Старый 16.08.2007, 20:37   #1 (permalink)
Пользователь
 
Аватар для MisterVic
 
Регистрация: 08.06.2007
Адрес: 2 Железнодорожная 34
Возраст: 29
Сообщений: 61
Репутация: 6
Провайдер: Спарк
Восклицание Delphi - Need help


Понадобилось тут написать маленькую прогу, которая бы скачивала файл на винт.
Порылся в исходниках, нашёл один, вставил, подправил. Всё вроде работает.
Выяснилось, что в условиях внезапного обрыва соединения и вылета приложения - докачка есть.
А вот от ресета или вырубленного питания - нет.
Может кто-нибудь помочь?
Привожу код:
Код:
var
  Form1: TForm1;
  stop: boolean; //<-|вспомогательная переменная отв. за
  //  |остановку скачки
hInet, //<-переменная сод. указатель на сессию
  hURL: HINTERNET; //<-указатель на URL
  fSize, //<-размер файла
  ReadLen, //<-количество реально прочитанных байт
  RestartPos: DWORD; //<-|позиция с которой начинается
  //  |докачка
  fBuf: array[1..1024] of byte; //<-буфер куда качаем
  f: file; //<-файл куда качаем
  Header: string; //<-|дополнительная переменная в HTTP
  //  |заголовок

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
 RestartPos := 0; //<- |инициализация
  fSize := 0; //<- |переменных
  Button1.Enabled := false;
  Button2.Enabled := true;
  //Если на винте есть файл то считаем, что нужно докачивать
  if FileExists('c:\123.tmp') then
  begin
    AssignFile(f, 'c:\123.tmp');
    Reset(f, 1);
    RestartPos := (FileSize(F));
    Seek(F, FileSize(F));
  end
  else
  begin
    //иначе с начала
    AssignFile(f, 'c:\123.tmp');
    ReWrite(f, 1);
  end;
  //открываем сессию
  hInet := InternetOpen('Mozilla',
    PRE_CONFIG_INTERNET_ACCESS,
    nil,
    nil,
    0);
  //Пишем дополнительную строку для заголовка
  Header := 'Accept: */*';
  //открываем URL
  hURL := InternetOpenURL(hInet,
    PChar(Edit1.Text),
    pchar(Header),
    StrLen(pchar(Header)),
    0,
    0);
  //устанавливаем позицию в файле для докачки
  if RestartPos > 0 then
    InternetSetFilePointer(hURL,
      FileSize(f),
      nil,
      File_Begin,
      0);

      ClientSocket1.

  //смотрим ск-ко надо скачать
  InternetQueryDataAvailable(hURL, fSize, 0, 0);
  if RestartPos > 0 then
  begin
    ProgressBar1.Min := 0;
    ProgressBar1.Max := fSize + RestartPos;
    ProgressBar1.Position := RestartPos;
  end
  else
  begin
    ProgressBar1.Min := 0;
    ProgressBar1.Max := fSize + RestartPos;
  end;
  //качаем до тех пор пока реально прочитаное число байт не
  //будет равно нулю или не стоg
  while (ReadLen <> 0) and (stop = false) do
  begin
    //читаем в буфер
    InternetReadFile(hURL, @fBuf, SizeOf(fBuf), ReadLen);
    //смотрим ск-ко осталось докачать
    InternetQueryDataAvailable(hURL, fSize, 0, 0);
    ProgressBar1.Position := ProgressBar1.Max - fSize;
    BlockWrite(f, fBuf, ReadLen); //<-пишем в файл
    Application.ProcessMessages;
  end;
  stop := false;
  Button1.Enabled := true;
  Button2.Enabled := false;
  InternetCloseHandle(hURL); //<-|закрываем
  InternetCloseHandle(hInet); //<-|сесcии
  CloseFile(f); //<-|и файл
MisterVic вне форума   Ответить с цитированием
Старый 16.08.2007, 21:59   #2 (permalink)
Местный
 
Аватар для Grand Father
 
Регистрация: 03.03.2007
Адрес: Москва, Люблино
Возраст: 33
Сообщений: 946
Репутация: 132
Провайдер: Другой


На ум приходит только одно: после обрыва связи/вылета приложения файл успевает закрыться (т.е. частично сохраниться на винте), а в момент отключения питания - не успевает (иначе filesize возвращал бы не 0 и продолжалась докачка). Следовательно, надо его как-нибудь принудительно сохранять в момент получения очередной порции данных (т.е. закрывать и открывать заново с записью в конец).

PS Блин, давно паскалевских сырцов не видел. Еще понимаю чего-то. Прикольно!
Grand Father вне форума   Ответить с цитированием
Старый 16.08.2007, 22:52   #3 (permalink)
Местный
 
У меня нет аватара
 
Регистрация: 05.08.2007
Возраст: 44
Сообщений: 111
Репутация: 32


А винда у тебя 95/98я? Или 200/XP/Vista? Для большей корректности после каждой записи делай операцию Close/Open/FileSize/Seek.
Stranger вне форума   Ответить с цитированием
Старый 16.08.2007, 23:01   #4 (permalink)
Пользователь
 
Аватар для MisterVic
 
Регистрация: 08.06.2007
Адрес: 2 Железнодорожная 34
Возраст: 29
Сообщений: 61
Репутация: 6
Провайдер: Спарк


Windows XP.
И пишу с расчётом на него.
Цитата:
Сообщение от Grand Father
На ум приходит только одно: после обрыва связи/вылета приложения файл успевает закрыться (т.е. частично сохраниться на винте)
Ну я специально прописал закрытие в эти случаи как раз
Цитата:
Сообщение от Grand Father
Следовательно, надо его как-нибудь принудительно сохранять в момент получения очередной порции данных (т.е. закрывать и открывать заново с записью в конец).
Попробую, спасибо за идею
MisterVic вне форума   Ответить с цитированием
Ответ




Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Вкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi и потоки Sky Программирование 11 26.03.2007 20:34


кулон
При копировании информации ссылка на источник обязательна!

Часовой пояс GMT +4, время: 04:11.
vBulletin® Version 3.8.2.Copyright ©2000 - 2012, Jelsoft Enterprises Ltd. Перевод: zCarot
Template-Modifications by TMS