提交 fb61af18 编写于 作者: A Arjen Poutsma

Allow "release on close" for DataBuffer.asInputStream

This commit introduces DataBuffer.asInputStream(boolean), that can
release the underlying buffer when the stream is closed.

Furthermore, this commit adds additional javadoc.

Issue: SPR-16444
上级 4318710b
...@@ -248,11 +248,25 @@ public interface DataBuffer { ...@@ -248,11 +248,25 @@ public interface DataBuffer {
/** /**
* Expose this buffer's data as an {@link InputStream}. Both data and read position are * Expose this buffer's data as an {@link InputStream}. Both data and read position are
* shared between the returned stream and this data buffer. * shared between the returned stream and this data buffer. The underlying buffer will
* <strong>not</strong> be {@linkplain DataBufferUtils#release(DataBuffer) released} when the
* input stream is {@linkplain InputStream#close() closed}.
* @return this data buffer as an input stream * @return this data buffer as an input stream
* @see #asInputStream(boolean)
*/ */
InputStream asInputStream(); InputStream asInputStream();
/**
* Expose this buffer's data as an {@link InputStream}. Both data and read position are
* shared between the returned stream and this data buffer.
* @param releaseOnClose whether the underlying buffer will be
* {@linkplain DataBufferUtils#release(DataBuffer) released} when the input stream is
* {@linkplain InputStream#close() closed}.
* @return this data buffer as an input stream
* @since 5.0.4
*/
InputStream asInputStream(boolean releaseOnClose);
/** /**
* Expose this buffer's data as an {@link OutputStream}. Both data and write position are * Expose this buffer's data as an {@link OutputStream}. Both data and write position are
* shared between the returned stream and this data buffer. * shared between the returned stream and this data buffer.
......
...@@ -365,6 +365,11 @@ public class DefaultDataBuffer implements DataBuffer { ...@@ -365,6 +365,11 @@ public class DefaultDataBuffer implements DataBuffer {
return new DefaultDataBufferInputStream(); return new DefaultDataBufferInputStream();
} }
@Override
public InputStream asInputStream(boolean releaseOnClose) {
return new DefaultDataBufferInputStream();
}
@Override @Override
public OutputStream asOutputStream() { public OutputStream asOutputStream() {
return new DefaultDataBufferOutputStream(); return new DefaultDataBufferOutputStream();
......
...@@ -250,6 +250,11 @@ public class NettyDataBuffer implements PooledDataBuffer { ...@@ -250,6 +250,11 @@ public class NettyDataBuffer implements PooledDataBuffer {
return new ByteBufInputStream(this.byteBuf); return new ByteBufInputStream(this.byteBuf);
} }
@Override
public InputStream asInputStream(boolean releaseOnClose) {
return new ByteBufInputStream(this.byteBuf, releaseOnClose);
}
@Override @Override
public OutputStream asOutputStream() { public OutputStream asOutputStream() {
return new ByteBufOutputStream(this.byteBuf); return new ByteBufOutputStream(this.byteBuf);
......
...@@ -182,6 +182,27 @@ public class DataBufferTests extends AbstractDataBufferAllocatingTestCase { ...@@ -182,6 +182,27 @@ public class DataBufferTests extends AbstractDataBufferAllocatingTestCase {
release(buffer); release(buffer);
} }
@Test
public void inputStreamReleaseOnClose() throws IOException {
DataBuffer buffer = createDataBuffer(3);
byte[] bytes = {'a', 'b', 'c'};
buffer.write(bytes);
InputStream inputStream = buffer.asInputStream(true);
try {
byte[] result = new byte[3];
int len = inputStream.read(result);
assertEquals(3, len);
assertArrayEquals(bytes, result);
} finally {
inputStream.close();
}
// AbstractDataBufferAllocatingTestCase.LeakDetector will verify the buffer's release
}
@Test @Test
public void outputStream() throws IOException { public void outputStream() throws IOException {
DataBuffer buffer = createDataBuffer(4); DataBuffer buffer = createDataBuffer(4);
......
...@@ -35,6 +35,7 @@ import reactor.core.publisher.Flux; ...@@ -35,6 +35,7 @@ import reactor.core.publisher.Flux;
import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.PooledDataBuffer; import org.springframework.core.io.buffer.PooledDataBuffer;
import org.springframework.http.HttpCookie; import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
...@@ -210,8 +211,14 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest { ...@@ -210,8 +211,14 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest {
@Override @Override
public boolean release() { public boolean release() {
this.pooledByteBuffer.close(); boolean result;
return this.pooledByteBuffer.isOpen(); try {
result = DataBufferUtils.release(this.dataBuffer);
}
finally {
this.pooledByteBuffer.close();
}
return result && this.pooledByteBuffer.isOpen();
} }
@Override @Override
...@@ -338,6 +345,11 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest { ...@@ -338,6 +345,11 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest {
return this.dataBuffer.asInputStream(); return this.dataBuffer.asInputStream();
} }
@Override
public InputStream asInputStream(boolean releaseOnClose) {
return this.dataBuffer.asInputStream(releaseOnClose);
}
@Override @Override
public OutputStream asOutputStream() { public OutputStream asOutputStream() {
return this.dataBuffer.asOutputStream(); return this.dataBuffer.asOutputStream();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册