Я в настоящее время пытаюсь передать содержание потоком к сети после процесса транскодирования. Это обычно хорошо работает путем выписывания двоичного файла к моему веб-потоку, но некоторым браузерам (конкретно IE7, IE8) не нравится не определять Довольную Длину в HTTP-заголовке. Я полагаю, что "действительные" заголовки, как предполагается, имеют этот набор.
Что надлежащий путь состоит в том, чтобы передать содержание потоком к сети, когда у Вас есть неизвестная Довольная Длина? Процесс транскодирования может взять некоторое время, таким образом, я хочу начать передавать его потоком, как он завершается.
Попробуйте отправить их по частям вместе с Transfer-Encoding:
chunked
. Подробнее в википедии .
Обновите в соответствии с комментариями, вот пример того, как "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(....);
Вы видите в исходном коде каждый фрагмент of data существуют заголовок, который представляет длину данных в шестнадцатеричном формате, CRLF, фактические данные и CRLF. Конец потока представлен заголовком, обозначающим длину 0 и два CRLF.
Примечание: несмотря на пример, вам действительно не он нужен в веб-приложении на основе JSP / сервлета. Если для ответа не задана длина содержимого, веб-контейнер автоматически передает его фрагментами.
В продолжение отличного сообщения BalusC, вот код, который я использую в C#. Я выгружаю данные вручную непосредственно в выходной поток HTTP, после получения данных из STDOUT процесса.
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);