这是一个演示我的问题的 JUnit 测试:
package stream;
import static org.junit.jupiter.api.Assertions.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.junit.jupiter.api.Test;
class StreamTest {
public static class LoopbackStream {
private final byte[] END_MARKER = new byte[0];
private final ArrayBlockingQueue<byte[]> queue = new ArrayBlockingQueue<>(1024);
public OutputStream getOutputStream() {
return new OutputStream() {
@Override
public void write(int b) throws IOException {
this.write(new byte[] { (byte) b });
}
@Override
public void write(byte[] b, int off, int len) {
try {
queue.put(Arrays.copyOfRange(b, off, len - off));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
@Override
public void close() {
try {
queue.put(END_MARKER);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
}
public InputStream getInputStream() {
return new InputStream() {
private boolean finished = false;
private ByteBuffer current = ByteBuffer.wrap(new byte[0]);
@Override
public int read() {
if (ensureData()) {
return Byte.toUnsignedInt(current.get());
} else {
return -1;
}
}
@Override
public int read(byte[] b, int off, int len) {
if (ensureData()) {
int position = current.position();
current.get(b, off, Math.min(len, current.remaining()));
return current.position() - position;
} else {
return -1;
}
}
private boolean ensureData() {
if (!finished && !current.hasRemaining()) {
try {
byte[] data = queue.take();
current = ByteBuffer.wrap(data);
finished = data == END_MARKER;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
return !finished;
}
};
}
}
@Test
void testVanilla() throws IOException {
LoopbackStream objectUnderTest = new LoopbackStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(objectUnderTest.getOutputStream()), true);
BufferedReader br = new BufferedReader(new InputStreamReader(objectUnderTest.getInputStream()));
pw.println("Hello World!");
assertEquals("Hello World!", br.readLine());
}
@Test
void testVanilla2() throws IOException {
LoopbackStream objectUnderTest = new LoopbackStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(objectUnderTest.getOutputStream()), true);
BufferedReader br = new BufferedReader(new InputStreamReader(objectUnderTest.getInputStream()));
pw.println("Hello World!");
assertEquals("Hello World!", br.readLine());
pw.println("Hello Otherworld!");
assertEquals("Hello Otherworld!", br.readLine());
}
@Test
void testGzipped() throws IOException {
LoopbackStream objectUnderTest = new LoopbackStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new GZIPOutputStream(objectUnderTest.getOutputStream(), true)), true);
BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(objectUnderTest.getInputStream())));
pw.println("Hello World!");
assertEquals("Hello World!", br.readLine());
}
}
有两个单独的测试。一个使用普通输入和输出流(工作正常),另一个将这些流包装在它们的 gzip 等效项中。
我使用了GZIPOutputStream
'ssyncFlush
选项,我希望在刷新父流时自动刷新流中的所有剩余字节。每当它执行PrintWriter
.autoFlush
println
有没有更好的方法来强制GZIPOutputStream
在 a 之后刷新其缓冲区println
?