2012-04-17 3 views
0

я следующий код, который загружает файл на сервер, сделав запрос POST:HttpWebRequest - отправка файла кусками и отслеживания прогресса

string fileName = @"C:\Console_sk.txt"; 

HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create("http://" + Environment.MachineName + ":8000/Upload"); 
request.Method = "POST"; 
request.ContentType = "text/plain"; 
request.AllowWriteStreamBuffering = false; 

Stream fileStream = new FileStream(fileName, FileMode.Open); 
request.ContentLength = fileStream.Length; 

Stream serverStream = request.GetRequestStream(); 

byte[] buffer = new byte[4096]; 
while (true) 
{ 
    int bytesRead = fileStream.Read(buffer, 0, buffer.Length); 
    if (bytesRead > 0) 
    { 
     serverStream.Write(buffer, 0, bytesRead);  
    } 
    else 
    { 
     break; 
    } 
} 

serverStream.Close(); 
fileStream.Close(); 

request.GetResponse(); 

Это будет использоваться для загрузки потенциально больших файлов, поэтому для нас важно отслеживать ход этой загрузки.

Основываясь на various sources, я думал, что мой код будет загружать файл в 4096 байтовых кусках, т. Е. Будет сделано несколько запросов POST. Но при отслеживании запросов с помощью Fiddler это показывает, что сделан только один запрос POST. С другой стороны, когда я включил .NET network tracing, результирующий журнал показал, что 4096 байтовых блоков действительно записаны для запроса потока, и сокет всегда открывается для каждой операции записи.

Мое понимание сети в целом довольно плохое, поэтому я не совсем понимаю, как это действительно работает. При вызове serverStream.Write, предоставленный кусок действительно отправлен по сети, или он просто буферизуется где-то? И когда вызывается serverStream.Close, могу ли я быть уверенным, что весь файл был загружен?

ответ

2

Класс HttpWebRequest отправляет одиночный HTTP-запрос. Что вы делаете, так это то, что вы пишете запрос в кусках, чтобы не загружать весь файл в память. Вы читаете из файла и напрямую записываете в поток запросов в кусках 4 КБ.

При вызове serverStream.Write, это при условии, кусок действительно передается по сети

Да, это написано в сетевой розетке.

+0

Благодарим за это. Как насчет моего второго вопроса относительно 'serverStream.Close'? –

+0

Когда вы закрываете поток запросов, все данные будут записаны в сокет. На самом деле вы не должны закрывать эти IDisposable ресурсы вручную, как и вы. Вы должны обернуть их в выражения 'using', чтобы обеспечить правильное удаление даже в случае ошибки. –

+0

Хм, теперь я снова смущен :). Сначала вы написали, что кусок записывается в сокет, когда вызывается 'Write'. Теперь вы говорите, что все данные будут записаны в сокет, когда вызывается 'Close'. Я был бы очень благодарен, если бы вы могли объяснить все это в более простых выражениях, возможно, что-то еще не хватает. Спасибо, что нашли меня здесь! –

Смежные вопросы