Как загрузить файл с помощью XMLHTTP?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Как загрузить файл с помощью XMLHTTP?

Сообщение ANDLL » 03.07.2006 (Пн) 16:58

Делаю так:
Код: Выделить всё
            nRequest.open "get", nUrl, True
            nRequest.Send
            Do Until nRequest.readyState = READYSTATE_COMPLETE
                DoEvents
                Sleep 100
            Loop
            If nRequest.STATUS = 200 Then
                Dim nUpdateFile As String
                nUpdateFile = GetTemporaryFile
                fn = FreeFile
                Open nUpdateFile For Binary As #fn
                    Put #fn, , nRequest.responseText
                Close #fn
            End If

Однако если файл двоичный, он доходит мягко говоря "подпорченым". А как его сохранить так что бы он полностью совпал с тем файлом, что лежал на сервере?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 03.07.2006 (Пн) 17:05

Сохраняй не responseText, а responseBody: там байтовый массив.

Кроме того, есть более кошерные способы дождаться конца загрузки, чем цикл с DoEvents.
Изображение

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 03.07.2006 (Пн) 17:08

Ну а такие проперти как responseStream не посмотреть? ;)

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 03.07.2006 (Пн) 17:43

RayShade писал(а):Ну а такие проперти как responseStream не посмотреть? ;)
И что с ним делать?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 03.07.2006 (Пн) 17:48

2tyomitch:С responseBody та же байда:(
А что там за кошерные способы?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 03.07.2006 (Пн) 18:42

ANDLL

Ну как.

Пиши его, в файл :)



tyomitch

У объекта нет эвентов.

Как сделать кашерно в этом случае? :)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 03.07.2006 (Пн) 20:19

RayShade писал(а):ANDLL
Ну как.
Пиши его, в файл :)

IStream-то? Ну-ну.

RayShade писал(а):tyomitch
У объекта нет эвентов.
Как сделать кашерно в этом случае? :)

http://bbs.vbstreets.ru/viewtopic.php?p=6615910#6615910
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 8:09

2tyomitch:Почему мне цикл с DoEvents нравится больше? Даже если бы у него и были события, я все равно юзал бы цикл с DoEvents.. Просто мне нудна синхронная закачка с возможностью отмены, и все...
Но все равно за способ спасибо.
2RayShade:Может приведеш пример кода, где его надо прогсто "писать в файл"?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 9:08

Код: Выделить всё
Dim Data() As Byte
nRequest.Open "POST", nUrl, True
nRequest.setRequestHeader "Content-Type", "image/gif;"
nRequest.send
Do Until nRequest.readyState = READYSTATE_COMPLETE
    DoEvents
Loop
Data = nRequest.responseBody 'и делай с ним что хошь
Sleep тут абсолютно лишнее, да и насчет цикла с DoEvents Тёмыч прав. Какой смысл в асинхронном запросе, если твоя функция все равно блокирует основной поток? Хотя это справедливо только для библиотек. В форме можно и DoEvents обойтись. Но за Sleep в любом случае низачот.

PS. Это сезонное обострение чтоли? Всех на асинхронность тянет...
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 9:36

Sleep тут абсолютно лишнее
Да?
да и насчет цикла с DoEvents Тёмыч прав. Какой смысл в асинхронном запросе, если твоя функция все равно блокирует основной поток?
Ну почитай ты топик. Люблю вопросы ответы на которые написаны строчкой выше.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Сообщение ALX_2002 » 04.07.2006 (Вт) 10:09


ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 10:17

Гм. Как оказалось, для put'а надо произвести явное преобразование responseBosy из Variant'а(коим он объявлен) к Byte() коим он является после завершения общения с сервером.
Т.е.:
Код: Выделить всё
DIm nArr() as Byte
nArr=.responseBofy
Put #1,,nArr

Тогда работает.
Ну в общем, всем спасибо.
2ALX_2002:Если честно, лень проверять твой вариант, учитывая что вопрос всетаки решен.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 10:22

ANDLL писал(а):
Sleep тут абсолютно лишнее
Да?
Да! Как ты, допустим, нажмешь кнопку отмены, если поток заморожен Sleep'ом?
ANDLL писал(а):
да и насчет цикла с DoEvents Тёмыч прав. Какой смысл в асинхронном запросе, если твоя функция все равно блокирует основной поток?
Ну почитай ты топик. Люблю вопросы ответы на которые написаны строчкой выше.
В свою очередь советую еще раз перечитать мой ответ :wink:
Я писал(а):Хотя это справедливо только для библиотек. В форме можно и DoEvents обойтись.
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 11:58

Antonariy писал(а):
ANDLL писал(а):
Sleep тут абсолютно лишнее
Да?
Да! Как ты, допустим, нажмешь кнопку отмены, если поток заморожен Sleep'ом
Sleep снижает нагрузку на процессор(которая при его отсутсвии от данного потока будет составлять 100%) практически до 0... Ну по крайней мере значительно снижает. События нажатия на кнопку будут происходить максимум через 100 мс после нажатия на кнопку, что врядли ктонибудь заметит.
И кому низачет ;)
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 12:22

Тебе :wink: Я уже себе низачот по этой теме ставил. Просто в случе со слипом получается рулетка - можешь ткнуть в момент слипа и ничего не произойдет, клик в очередь не поставится, я когда-то это проверял.

Ну, 100% не будет, около 90, но это почти ни на что не влияет. Поробуй запусти вместе с циклом какую-нибуть тяжеловесную прогу и увидишь, как проценты цикла отдадутся этой проге, причем разница в скорости работы этой проги с наличием в памяти цикла и без будет почти незаметна. Если ты поставишь в цикл Debug.Print, то увидишь, что цикл будет выполняться реже, а клики, кстати, в очередь поставятся и обработаются.
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 12:35

Просто в случе со слипом получается рулетка - можешь ткнуть в момент слипа и ничего не произойдет, клик в очередь не поставится, я когда-то это проверял.
Проверь еще раз и нормально. Все там происходит. Как получается что такой великий проффесионал как вы никогда не слышал про очередь сообщений?
Ну, 100% не будет, около 90, но это почти ни на что не влияет
Опять же. Ты наверное проверял прежде чем писать? И наверное не на машине с Penrium Pro и Win 3.11?
Поробуй запусти вместе с циклом какую-нибуть тяжеловесную прогу и увидишь, как проценты цикла отдадутся этой проге, причем разница в скорости работы этой проги с наличием в памяти цикла и без будет почти незаметна. Если ты поставишь в цикл Debug.Print, то увидишь, что цикл будет выполняться реже, а клики, кстати, в очередь поставятся и обработаются.
Ух ты! А я и не знал что мой Windows XP - многозадачная опреционная система! Наверное это со вторым сервис паком такая возможнгость появилась? А я все думал, что пока мой цикл выполняются люая другая прога не сможет вообще работать.... Экая оказия...
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 12:38

Возможно, насчет очереди и слипа ошибаюсь. Воспоминания начали всплывать, и всплыло, что у меня был не слип, а WaitForSingleObject, который как раз и ждал клика какой-то период времени.
Лучший способ понять что-то самому — объяснить это другому.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 12:41

Уговорил, чертяка языкастый :P
Оставляй Sleep :!:
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 13:10

Интересно, что почерпнул г-н Antonariy из всего топика?
И, кстати, почти наверняка при WaitForSingleObject то же все сообщения будут кидаться в очередь.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 13:56

В принципе ничего полезного. Я бы проверял состояние по таймеру. Но если ты тащишься от DoEvents + Sleep... Хозяин - барин.
При WaitForSingleObject была ситуация наоборот - клики могли возникать в момент, когда выполняется прочий код, а не Wait.
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.07.2006 (Вт) 15:32

При WaitForSingleObject была ситуация наоборот - клики могли возникать в момент, когда выполняется прочий код, а не Wait.

Antonariy низачет за буйную фантазию и отсутствие здравого смысла(можно подумать, WaitForSingleObject сильно отличается от Sleep).
Для проверки:
Код: Выделить всё
Option Explicit
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Const GENERIC_ALL = &H10000000

'Command1.Caption="Wait!"
Private Sub Command1_Click()
    Dim hProcess As Long
    hProcess = OpenProcess(GENERIC_ALL, 0, 2044)'<'exist process id here>
    WaitForSingleObject hProcess, 10000
End Sub

Private Sub Form_Click()
    MsgBox "Ckicked;)"
End Sub
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.07.2006 (Вт) 21:59

Этот код очень далек от того, что был у меня. Я экспериментировал с потоками и кнопкой запускал событие для прибития потока, которое ожидал wait в течении короткого промежутка времени. Никак не 10000. Остальное время цикл выполнял другие полезные функции. Поэтому событие редко ловилось с первого клика.

Кстати я вообще не понимаю, что означает этот код, кроме Form_Click. И hProcess всегда = 0.
Лучший способ понять что-то самому — объяснить это другому.

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 04.07.2006 (Вт) 22:36

Antonariy
А ты что просто скопировал код и запустил, не читая комментариев? (<'exist process id here>) :roll:
Если всё делать своими ручками, они скоро отвалятся !

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.07.2006 (Ср) 9:47

2Antonariy:
А может в том твоем "далеком" коде не было DoEvents :roll:
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 05.07.2006 (Ср) 11:31

ANDLL
Не было. Цикл же в отдельном потоке, нафига ему DoEvents? И так прибить можно.

Kovu
В принципе ты прав :roll: Смотрел пост уже будучи несколько на бровях и не догадался вставить GetCurrentProcessId
Лучший способ понять что-то самому — объяснить это другому.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.07.2006 (Ср) 12:14

Antonariy писал(а):Kovu
В принципе ты прав :roll: Смотрел пост уже будучи несколько на бровях и не догадался вставить GetCurrentProcessId

WaitForSingleObject(OpenProcess(GetCurrentProcessId)) :?:
Может, ты и сейчас на бровях? :-?
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.07.2006 (Ср) 12:15

Интересно, от одного меня ускользнул смысл написанного в этом, этом и этом сообщениях? В тех местах, где шли пустопорожние "наезды" и "низачеты" по поводу приема в программировании, настолько очевидного, что про это нигде, наверное, даже не говорится?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 05.07.2006 (Ср) 13:09

tyomitch
hProcess = OpenProcess(GENERIC_ALL, 0, GetCurrentProcessId)
Разве не так? Да, я периодически отвечаю, основываясь на полузабытых фактах, не проверив кодом, но не надо держать меня за идиота. И я признаю свои ошибки.

ANDLL
Про Sleep, Wait и очередь был неправ. Из остального что конкретно вызывает смущение?
Лучший способ понять что-то самому — объяснить это другому.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.07.2006 (Ср) 13:35

Antonariy писал(а):tyomitch
hProcess = OpenProcess(GENERIC_ALL, 0, GetCurrentProcessId)
Разве не так? Да, я периодически отвечаю, основываясь на полузабытых фактах, не проверив кодом, но не надо держать меня за идиота. И я признаю свои ошибки.

Если зачем-то есть намерение ждать конца текущего процесса, то совсем даже не нужно открывать его PID: он всегда открыт под хендлом -1.
Но я думаю, что в коде ANDLL имелся в виду PID чужого процесса, чтобы WaitForSingleObject когда-нибудь вернулся, и можно было проверить, что клик по форме прошёл успешно.
Изображение

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 05.07.2006 (Ср) 13:57

Про -1 не знал. ANDLL видимо тоже, иначе бы написал не кривую головоломку, а так:
Код: Выделить всё
Option Explicit
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Sub Command1_Click()
    WaitForSingleObject -1, 10000
End Sub

Private Sub Form_Click()
    MsgBox "Ckicked;)"
End Sub

Смысл всего лишь был в том, чтобы показать, что клик на форме при включенном Wait таки поставится в очередь.
Лучший способ понять что-то самому — объяснить это другому.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 55

    TopList