Java';s GZIPOutputStream拒绝刷新

Java';s GZIPOutputStream拒绝刷新,java,stream,gzipoutputstream,Java,Stream,Gzipoutputstream,下面是一个JUnit测试,它演示了我的问题: 包流; 导入静态org.junit.jupiter.api.Assertions.*; 导入java.io.BufferedReader; 导入java.io.IOException; 导入java.io.InputStream; 导入java.io.InputStreamReader; 导入java.io.OutputStream; 导入java.io.OutputStreamWriter; 导入java.io.PrintWriter; 导入jav

下面是一个JUnit测试,它演示了我的问题:

包流;
导入静态org.junit.jupiter.api.Assertions.*;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.io.PrintWriter;
导入java.nio.ByteBuffer;
导入java.util.array;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.zip.gzip输入流;
导入java.util.zip.GZIPOutputStream;
导入org.junit.jupiter.api.Test;
类流测试{
公共静态类LoopbackStream{
私有最终字节[]结束标记=新字节[0];
private final ArrayBlockingQueue=新ArrayBlockingQueue(1024);
public OutputStream getOutputStream(){
返回新的OutputStream(){
@凌驾
公共无效写入(int b)引发IOException{
写入(新字节[]{(字节)b});
}
@凌驾
公共无效写入(字节[]b,int off,int len){
试一试{
put(Arrays.copyOfRange(b,off,len-off));
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
@凌驾
公众假期结束(){
试一试{
队列放置(结束标记);
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
};
}
公共输入流getInputStream(){
返回新的InputStream(){
private boolean finished=false;
private ByteBuffer current=ByteBuffer.wrap(新字节[0]);
@凌驾
公共int read(){
如果(ensureData()){
返回Byte.toUnsignedInt(current.get());
}否则{
返回-1;
}
}
@凌驾
公共整数读取(字节[]b,整数关闭,整数长度){
如果(ensureData()){
int position=当前位置();
current.get(b,off,Math.min(len,current.remaining());
返回当前位置()-位置;
}否则{
返回-1;
}
}
私有布尔值ensureData(){
如果(!finished&!current.haslaining()){
试一试{
字节[]数据=queue.take();
当前=ByteBuffer.wrap(数据);
完成=数据==结束标记;
}捕捉(中断异常e){
Thread.currentThread().interrupt();
返回false;
}
}
返回!完成;
}
};
}
}
@试验
void testVanilla()引发IOException{
LoopbackStream objectUnderTest=新的LoopbackStream();
PrintWriter pw=新的PrintWriter(新的OutputStreamWriter(objectUnderTest.getOutputStream()),true);
BufferedReader br=新的BufferedReader(新的InputStreamReader(objectUnderTest.getInputStream());
println(“你好,世界!”);
assertEquals(“你好,世界!”,br.readLine());
}
@试验
void testVanilla2()引发IOException{
LoopbackStream objectUnderTest=新的LoopbackStream();
PrintWriter pw=新的PrintWriter(新的OutputStreamWriter(objectUnderTest.getOutputStream()),true);
BufferedReader br=新的BufferedReader(新的InputStreamReader(objectUnderTest.getInputStream());
println(“你好,世界!”);
assertEquals(“你好,世界!”,br.readLine());
println(“你好,另一个世界!”);
assertEquals(“Hello Otherworld!”,br.readLine());
}
@试验
void testgzip()引发IOException{
LoopbackStream objectUnderTest=新的LoopbackStream();
PrintWriter pw=new PrintWriter(new OutputStreamWriter(new GZIPOutputStream(objectundtest.getOutputStream(),true)),true);
BufferedReader br=新的BufferedReader(新的InputStreamReader(新的GZIPInputStream(objectUnderTest.getInputStream()));
println(“你好,世界!”);
assertEquals(“你好,世界!”,br.readLine());
}
}
有两个单独的测试。一种是使用普通的输入和输出流(工作正常),另一种是将这些流封装在gzip等价物中

我使用了
GZIPOutputStream
syncFlush
选项,希望在刷新父流时自动刷新流中的任何剩余字节。我正在使用
PrintWriter
autoFlush
选项在执行
println
时刷新其数据


有没有更好的方法来强制
GZIPOutputStream
println
之后刷新其缓冲区?

我知道这不是您问题的完整答案,但它太长,无法发表评论


更新:

经过进一步调查,似乎不是
GZIPOutputStream
没有刷新(通过在
公共无效写入中添加
System.out.println(“xy”);
语句(字节[]b,int off,int len)
方法您可以看到
gzipoutstream
将两个字节数组写入
OutputStream
:一个是gzip流头,另一个是第一行文本的编码内容)

由于
java.io.InputStreamRead之间的不良交互,读取过程似乎会阻塞
@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());
}