我目前正試圖在轉碼過程之後將內容流式傳輸到網絡。這通常可以通過將二進制文件寫入我的Web流而正常工作,但是某些瀏覽器(特別是IE7,IE8)不喜歡沒有在HTTP標頭中定義的Content-Length。我相信「有效」標題應該有這個集合。用於未知內容的HTTP頭長度
當您有一個未知的內容長度時,將內容傳輸到網絡的正確方法是什麼?轉碼過程可能需要一段時間,所以我想在它完成時開始流式傳輸。
我目前正試圖在轉碼過程之後將內容流式傳輸到網絡。這通常可以通過將二進制文件寫入我的Web流而正常工作,但是某些瀏覽器(特別是IE7,IE8)不喜歡沒有在HTTP標頭中定義的Content-Length。我相信「有效」標題應該有這個集合。用於未知內容的HTTP頭長度
當您有一個未知的內容長度時,將內容傳輸到網絡的正確方法是什麼?轉碼過程可能需要一段時間,所以我想在它完成時開始流式傳輸。
嘗試將它們連同Transfer-Encoding:
chunked
一起發送。 wikipedia中的更多詳細信息。
更新按照該意見,在這裏有一個例子是 「ChunkedOutputStream」 在Java中怎麼可能看起來像:
package com.stackoverflow.q2395192;
import java.io.IOException;
import java.io.OutputStream;
public class ChunkedOutputStream extends OutputStream {
private static final byte[] CRLF = "\r\n".getBytes();
private OutputStream output = null;
public ChunkedOutputStream(OutputStream output) {
this.output = output;
}
@Override
public void write(int i) throws IOException {
write(new byte[] { (byte) i }, 0, 1);
}
@Override
public void write(byte[] b, int offset, int length) throws IOException {
writeHeader(length);
output.write(CRLF, 0, CRLF.length);
output.write(b, offset, length);
output.write(CRLF, 0, CRLF.length);
}
@Override
public void flush() throws IOException {
output.flush();
}
@Override
public void close() throws IOException {
writeHeader(0);
output.write(CRLF, 0, CRLF.length);
output.write(CRLF, 0, CRLF.length);
output.close();
}
private void writeHeader(int length) throws IOException {
byte[] header = Integer.toHexString(length).getBytes();
output.write(header, 0, header.length);
}
}
...這基本上可以用作:
OutputStream output = new ChunkedOutputStream(response.getOutputStream());
output.write(....);
在源代碼中可以看到,每個數據塊都有一個表示十六進制數據長度,CRLF,實際數據和CRLF的標題。流的結尾由表示0長度的頭部和兩個CRLF表示。
注:儘管例子,你其實不需要它在一個JSP/Servlet的web應用。只要內容長度未在響應中設置,webcontainer就會自動將它們以塊的形式傳輸。
就跟BalusC的優秀帖子一樣,這裏是我在C#中使用的代碼。在從進程上的STDOUT接收到數據後,我將數據手動直接分塊爲HTTP輸出流。
int buffSize = 16384;
byte[] buffer = new byte[buffSize];
byte[] hexBuff;
byte[] CRLF = Encoding.UTF8.GetBytes("\r\n");
br = new BinaryReader(transcoder.StandardOutput.BaseStream);
//Begin chunking...
int ret = 0;
while (!transcoder.HasExited && (ret = br.Read(buffer, 0, buffSize)) > 0)
{
//Write hex length...
hexBuff = Encoding.UTF8.GetBytes(ret.ToString("X"));
e.Context.Stream.Write(hexBuff, 0, hexBuff.Length);
//Write CRLF...
e.Context.Stream.Write(CRLF, 0, CRLF.Length);
//Write byte content...
e.Context.Stream.Write(buffer, 0, ret);
//Write CRLF...
e.Context.Stream.Write(CRLF, 0, CRLF.Length);
}
//End chunking...
//Write hex length...
hexBuff = Encoding.UTF8.GetBytes(0.ToString("X"));
e.Context.Stream.Write(hexBuff, 0, hexBuff.Length);
好的工作,很高興它幫助你。 – BalusC 2010-03-08 18:20:33
我嘗試使用塊,並且Firefox在接收它們時會鎖定。我正在傳輸二進制數據,我是否必須將其轉換爲十六進制才能使用塊?有沒有.NET庫可用於此? – jocull 2010-03-07 17:52:41
不,你不需要轉換。如果不預先指定內容長度,我會希望.NET自動處理它。 – 2010-03-07 19:04:39
點擊'chunked'和維基百科鏈接後面的鏈接,瞭解它應該是什麼樣子。我不會做.NET,所以我不能付出太多的代價,但是我可以給出一個基於Java的示例,以擴展'OutputStream'的風格。讓我們知道你是否想看到它。 – BalusC 2010-03-08 00:37:36