![]() |
|
|
#1 (permalink) |
|
Пользователь
Регистрация: 08.06.2007
Адрес: 2 Железнодорожная 34
Возраст: 29
Сообщений: 61
|
Понадобилось тут написать маленькую прогу, которая бы скачивала файл на винт.
Порылся в исходниках, нашёл один, вставил, подправил. Всё вроде работает. Выяснилось, что в условиях внезапного обрыва соединения и вылета приложения - докачка есть. А вот от ресета или вырубленного питания - нет. Может кто-нибудь помочь? Привожу код: Код:
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); //<-|и файл
|
|
|
|
|
|
#2 (permalink) |
|
Местный
Регистрация: 03.03.2007
Адрес: Москва, Люблино
Возраст: 33
Сообщений: 946
|
На ум приходит только одно: после обрыва связи/вылета приложения файл успевает закрыться (т.е. частично сохраниться на винте), а в момент отключения питания - не успевает (иначе filesize возвращал бы не 0 и продолжалась докачка). Следовательно, надо его как-нибудь принудительно сохранять в момент получения очередной порции данных (т.е. закрывать и открывать заново с записью в конец).
PS Блин, давно паскалевских сырцов не видел. Еще понимаю чего-то. Прикольно! ![]() |
|
|
|
|
|
#3 (permalink) |
|
Местный
|
А винда у тебя 95/98я? Или 200/XP/Vista? Для большей корректности после каждой записи делай операцию Close/Open/FileSize/Seek.
|
|
|
|
|
|
#4 (permalink) | ||
|
Пользователь
Регистрация: 08.06.2007
Адрес: 2 Железнодорожная 34
Возраст: 29
Сообщений: 61
|
Windows XP.
И пишу с расчётом на него. Цитата:
![]() Цитата:
![]() |
||
|
|
|
![]() |
| Здесь присутствуют: 1 (пользователей: 0 , гостей: 1) | |
| Опции темы | |
| Опции просмотра | |
|
|
Похожие темы
|
||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| Delphi и потоки | Sky | Программирование | 11 | 26.03.2007 20:34 |