|
|
|
@ -56,6 +56,7 @@ public abstract class DataBufferUtils { |
|
|
|
|
|
|
|
|
|
|
|
private static final Consumer<DataBuffer> RELEASE_CONSUMER = DataBufferUtils::release; |
|
|
|
private static final Consumer<DataBuffer> RELEASE_CONSUMER = DataBufferUtils::release; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
// Reading
|
|
|
|
// Reading
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
@ -74,31 +75,31 @@ public abstract class DataBufferUtils { |
|
|
|
* {@link #readInputStream(Callable, DataBufferFactory, int)}, to be removed in Spring 5.1 |
|
|
|
* {@link #readInputStream(Callable, DataBufferFactory, int)}, to be removed in Spring 5.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Deprecated |
|
|
|
@Deprecated |
|
|
|
public static Flux<DataBuffer> read(InputStream inputStream, |
|
|
|
public static Flux<DataBuffer> read( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
InputStream inputStream, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
return readInputStream(() -> inputStream, dataBufferFactory, bufferSize); |
|
|
|
return readInputStream(() -> inputStream, dataBufferFactory, bufferSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Obtain a {@link InputStream} from the given supplier, and read it into a {@code Flux} of |
|
|
|
* Obtain a {@link InputStream} from the given supplier, and read it into a {@code Flux} |
|
|
|
* {@code DataBuffer}s. Closes the input stream when the flux is terminated. |
|
|
|
* of {@code DataBuffer}s. Closes the input stream when the flux is terminated. |
|
|
|
* @param inputStreamSupplier the supplier for the input stream to read from |
|
|
|
* @param inputStreamSupplier the supplier for the input stream to read from |
|
|
|
* @param dataBufferFactory the factory to create data buffers with |
|
|
|
* @param dataBufferFactory the factory to create data buffers with |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> readInputStream(Callable<InputStream> inputStreamSupplier, |
|
|
|
public static Flux<DataBuffer> readInputStream( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
Callable<InputStream> inputStreamSupplier, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(inputStreamSupplier, "'inputStreamSupplier' must not be null"); |
|
|
|
Assert.notNull(inputStreamSupplier, "'inputStreamSupplier' must not be null"); |
|
|
|
|
|
|
|
|
|
|
|
return readByteChannel(() -> Channels.newChannel(inputStreamSupplier.call()), |
|
|
|
return readByteChannel(() -> Channels.newChannel(inputStreamSupplier.call()), dataBufferFactory, bufferSize); |
|
|
|
dataBufferFactory, bufferSize); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Read the given {@code ReadableByteChannel} into a <strong>read-once</strong> {@code Flux} of |
|
|
|
* Read the given {@code ReadableByteChannel} into a <strong>read-once</strong> {@code Flux} |
|
|
|
* {@code DataBuffer}s. Closes the channel when the flux is terminated. |
|
|
|
* of {@code DataBuffer}s. Closes the channel when the flux is terminated. |
|
|
|
* <p>The resulting {@code Flux} can only be subscribed to once. See |
|
|
|
* <p>The resulting {@code Flux} can only be subscribed to once. See |
|
|
|
* {@link #readByteChannel(Callable, DataBufferFactory, int)} for a variant that supports |
|
|
|
* {@link #readByteChannel(Callable, DataBufferFactory, int)} for a variant that supports |
|
|
|
* multiple subscriptions. |
|
|
|
* multiple subscriptions. |
|
|
|
@ -110,8 +111,9 @@ public abstract class DataBufferUtils { |
|
|
|
* {@link #readByteChannel(Callable, DataBufferFactory, int)}, to be removed in Spring 5.1 |
|
|
|
* {@link #readByteChannel(Callable, DataBufferFactory, int)}, to be removed in Spring 5.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Deprecated |
|
|
|
@Deprecated |
|
|
|
public static Flux<DataBuffer> read(ReadableByteChannel channel, |
|
|
|
public static Flux<DataBuffer> read( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
ReadableByteChannel channel, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
return readByteChannel(() -> channel, dataBufferFactory, bufferSize); |
|
|
|
return readByteChannel(() -> channel, dataBufferFactory, bufferSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -123,8 +125,8 @@ public abstract class DataBufferUtils { |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> readByteChannel(Callable<ReadableByteChannel> channelSupplier, |
|
|
|
public static Flux<DataBuffer> readByteChannel( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
Callable<ReadableByteChannel> channelSupplier, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(channelSupplier, "'channelSupplier' must not be null"); |
|
|
|
Assert.notNull(channelSupplier, "'channelSupplier' must not be null"); |
|
|
|
Assert.notNull(dataBufferFactory, "'dataBufferFactory' must not be null"); |
|
|
|
Assert.notNull(dataBufferFactory, "'dataBufferFactory' must not be null"); |
|
|
|
@ -156,8 +158,9 @@ public abstract class DataBufferUtils { |
|
|
|
* Spring 5.1 |
|
|
|
* Spring 5.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Deprecated |
|
|
|
@Deprecated |
|
|
|
public static Flux<DataBuffer> read(AsynchronousFileChannel channel, |
|
|
|
public static Flux<DataBuffer> read( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
AsynchronousFileChannel channel, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
return readAsynchronousFileChannel(() -> channel, dataBufferFactory, bufferSize); |
|
|
|
return readAsynchronousFileChannel(() -> channel, dataBufferFactory, bufferSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -178,8 +181,9 @@ public abstract class DataBufferUtils { |
|
|
|
* in Spring 5.1 |
|
|
|
* in Spring 5.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Deprecated |
|
|
|
@Deprecated |
|
|
|
public static Flux<DataBuffer> read(AsynchronousFileChannel channel, |
|
|
|
public static Flux<DataBuffer> read( |
|
|
|
long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
AsynchronousFileChannel channel, long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
return readAsynchronousFileChannel(() -> channel, position, dataBufferFactory, bufferSize); |
|
|
|
return readAsynchronousFileChannel(() -> channel, position, dataBufferFactory, bufferSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -192,24 +196,22 @@ public abstract class DataBufferUtils { |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> readAsynchronousFileChannel( |
|
|
|
public static Flux<DataBuffer> readAsynchronousFileChannel( |
|
|
|
Callable<AsynchronousFileChannel> channelSupplier, |
|
|
|
Callable<AsynchronousFileChannel> channelSupplier, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return readAsynchronousFileChannel(channelSupplier, 0, dataBufferFactory, bufferSize); |
|
|
|
return readAsynchronousFileChannel(channelSupplier, 0, dataBufferFactory, bufferSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Obtain a {@code AsynchronousFileChannel} from the given supplier, and read it into a |
|
|
|
* Obtain a {@code AsynchronousFileChannel} from the given supplier, and read it into a |
|
|
|
* {@code Flux} of {@code DataBuffer}s, starting at the given position. Closes the channel when |
|
|
|
* {@code Flux} of {@code DataBuffer}s, starting at the given position. Closes the |
|
|
|
* the flux is terminated. |
|
|
|
* channel when the flux is terminated. |
|
|
|
* @param channelSupplier the supplier for the channel to read from |
|
|
|
* @param channelSupplier the supplier for the channel to read from |
|
|
|
* @param position the position to start reading from |
|
|
|
* @param position the position to start reading from |
|
|
|
* @param dataBufferFactory the factory to create data buffers with |
|
|
|
* @param dataBufferFactory the factory to create data buffers with |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> readAsynchronousFileChannel( |
|
|
|
public static Flux<DataBuffer> readAsynchronousFileChannel(Callable<AsynchronousFileChannel> channelSupplier, |
|
|
|
Callable<AsynchronousFileChannel> channelSupplier, |
|
|
|
|
|
|
|
long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(channelSupplier, "'channelSupplier' must not be null"); |
|
|
|
Assert.notNull(channelSupplier, "'channelSupplier' must not be null"); |
|
|
|
@ -242,8 +244,8 @@ public abstract class DataBufferUtils { |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> read(Resource resource, |
|
|
|
public static Flux<DataBuffer> read( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
Resource resource, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
return read(resource, 0, dataBufferFactory, bufferSize); |
|
|
|
return read(resource, 0, dataBufferFactory, bufferSize); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -262,13 +264,12 @@ public abstract class DataBufferUtils { |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @param bufferSize the maximum size of the data buffers |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
* @return a flux of data buffers read from the given channel |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> read(Resource resource, long position, |
|
|
|
public static Flux<DataBuffer> read( |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
Resource resource, long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
if (resource.isFile()) { |
|
|
|
if (resource.isFile()) { |
|
|
|
File file = resource.getFile(); |
|
|
|
File file = resource.getFile(); |
|
|
|
|
|
|
|
|
|
|
|
return readAsynchronousFileChannel( |
|
|
|
return readAsynchronousFileChannel( |
|
|
|
() -> AsynchronousFileChannel.open(file.toPath(), StandardOpenOption.READ), |
|
|
|
() -> AsynchronousFileChannel.open(file.toPath(), StandardOpenOption.READ), |
|
|
|
position, dataBufferFactory, bufferSize); |
|
|
|
position, dataBufferFactory, bufferSize); |
|
|
|
@ -283,8 +284,6 @@ public abstract class DataBufferUtils { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
// Writing
|
|
|
|
// Writing
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
@ -295,16 +294,13 @@ public abstract class DataBufferUtils { |
|
|
|
* <strong>not</strong> {@linkplain #release(DataBuffer) release} the data buffers in the |
|
|
|
* <strong>not</strong> {@linkplain #release(DataBuffer) release} the data buffers in the |
|
|
|
* source. If releasing is required, then subscribe to the returned {@code Flux} with a |
|
|
|
* source. If releasing is required, then subscribe to the returned {@code Flux} with a |
|
|
|
* {@link #releaseConsumer()}. |
|
|
|
* {@link #releaseConsumer()}. |
|
|
|
* <p>Note that the writing process does not start until the returned {@code Flux} is subscribed |
|
|
|
* <p>Note that the writing process does not start until the returned {@code Flux} is subscribed to. |
|
|
|
* to. |
|
|
|
|
|
|
|
* @param source the stream of data buffers to be written |
|
|
|
* @param source the stream of data buffers to be written |
|
|
|
* @param outputStream the output stream to write to |
|
|
|
* @param outputStream the output stream to write to |
|
|
|
* @return a flux containing the same buffers as in {@code source}, that starts the writing |
|
|
|
* @return a flux containing the same buffers as in {@code source}, that starts the writing |
|
|
|
* process when subscribed to, and that publishes any writing errors and the completion signal |
|
|
|
* process when subscribed to, and that publishes any writing errors and the completion signal |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> write(Publisher<DataBuffer> source, |
|
|
|
public static Flux<DataBuffer> write(Publisher<DataBuffer> source, OutputStream outputStream) { |
|
|
|
OutputStream outputStream) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(source, "'source' must not be null"); |
|
|
|
Assert.notNull(source, "'source' must not be null"); |
|
|
|
Assert.notNull(outputStream, "'outputStream' must not be null"); |
|
|
|
Assert.notNull(outputStream, "'outputStream' must not be null"); |
|
|
|
|
|
|
|
|
|
|
|
@ -318,21 +314,17 @@ public abstract class DataBufferUtils { |
|
|
|
* <strong>not</strong> {@linkplain #release(DataBuffer) release} the data buffers in the |
|
|
|
* <strong>not</strong> {@linkplain #release(DataBuffer) release} the data buffers in the |
|
|
|
* source. If releasing is required, then subscribe to the returned {@code Flux} with a |
|
|
|
* source. If releasing is required, then subscribe to the returned {@code Flux} with a |
|
|
|
* {@link #releaseConsumer()}. |
|
|
|
* {@link #releaseConsumer()}. |
|
|
|
* <p>Note that the writing process does not start until the returned {@code Flux} is subscribed |
|
|
|
* <p>Note that the writing process does not start until the returned {@code Flux} is subscribed to. |
|
|
|
* to. |
|
|
|
|
|
|
|
* @param source the stream of data buffers to be written |
|
|
|
* @param source the stream of data buffers to be written |
|
|
|
* @param channel the channel to write to |
|
|
|
* @param channel the channel to write to |
|
|
|
* @return a flux containing the same buffers as in {@code source}, that starts the writing |
|
|
|
* @return a flux containing the same buffers as in {@code source}, that starts the writing |
|
|
|
* process when subscribed to, and that publishes any writing errors and the completion signal |
|
|
|
* process when subscribed to, and that publishes any writing errors and the completion signal |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> write(Publisher<DataBuffer> source, |
|
|
|
public static Flux<DataBuffer> write(Publisher<DataBuffer> source, WritableByteChannel channel) { |
|
|
|
WritableByteChannel channel) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(source, "'source' must not be null"); |
|
|
|
Assert.notNull(source, "'source' must not be null"); |
|
|
|
Assert.notNull(channel, "'channel' must not be null"); |
|
|
|
Assert.notNull(channel, "'channel' must not be null"); |
|
|
|
|
|
|
|
|
|
|
|
Flux<DataBuffer> flux = Flux.from(source); |
|
|
|
Flux<DataBuffer> flux = Flux.from(source); |
|
|
|
|
|
|
|
|
|
|
|
return Flux.create(sink -> |
|
|
|
return Flux.create(sink -> |
|
|
|
flux.subscribe(dataBuffer -> { |
|
|
|
flux.subscribe(dataBuffer -> { |
|
|
|
try { |
|
|
|
try { |
|
|
|
@ -357,40 +349,36 @@ public abstract class DataBufferUtils { |
|
|
|
* <strong>not</strong> {@linkplain #release(DataBuffer) release} the data buffers in the |
|
|
|
* <strong>not</strong> {@linkplain #release(DataBuffer) release} the data buffers in the |
|
|
|
* source. If releasing is required, then subscribe to the returned {@code Flux} with a |
|
|
|
* source. If releasing is required, then subscribe to the returned {@code Flux} with a |
|
|
|
* {@link #releaseConsumer()}. |
|
|
|
* {@link #releaseConsumer()}. |
|
|
|
* <p>Note that the writing process does not start until the returned {@code Flux} is subscribed |
|
|
|
* <p>Note that the writing process does not start until the returned {@code Flux} is subscribed to. |
|
|
|
* to. |
|
|
|
|
|
|
|
* @param source the stream of data buffers to be written |
|
|
|
* @param source the stream of data buffers to be written |
|
|
|
* @param channel the channel to write to |
|
|
|
* @param channel the channel to write to |
|
|
|
* @return a flux containing the same buffers as in {@code source}, that starts the writing |
|
|
|
* @return a flux containing the same buffers as in {@code source}, that starts the writing |
|
|
|
* process when subscribed to, and that publishes any writing errors and the completion signal |
|
|
|
* process when subscribed to, and that publishes any writing errors and the completion signal |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Flux<DataBuffer> write(Publisher<DataBuffer> source, AsynchronousFileChannel channel, |
|
|
|
public static Flux<DataBuffer> write( |
|
|
|
long position) { |
|
|
|
Publisher<DataBuffer> source, AsynchronousFileChannel channel, long position) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(source, "'source' must not be null"); |
|
|
|
Assert.notNull(source, "'source' must not be null"); |
|
|
|
Assert.notNull(channel, "'channel' must not be null"); |
|
|
|
Assert.notNull(channel, "'channel' must not be null"); |
|
|
|
Assert.isTrue(position >= 0, "'position' must be >= 0"); |
|
|
|
Assert.isTrue(position >= 0, "'position' must be >= 0"); |
|
|
|
|
|
|
|
|
|
|
|
Flux<DataBuffer> flux = Flux.from(source); |
|
|
|
Flux<DataBuffer> flux = Flux.from(source); |
|
|
|
|
|
|
|
|
|
|
|
return Flux.create(sink -> { |
|
|
|
return Flux.create(sink -> { |
|
|
|
BaseSubscriber<DataBuffer> subscriber = |
|
|
|
flux.subscribe(new AsynchronousFileChannelWriteCompletionHandler(sink, channel, position)); |
|
|
|
new AsynchronousFileChannelWriteCompletionHandler(sink, channel, position); |
|
|
|
|
|
|
|
flux.subscribe(subscriber); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void closeChannel(@Nullable Channel channel) { |
|
|
|
private static void closeChannel(@Nullable Channel channel) { |
|
|
|
try { |
|
|
|
if (channel != null && channel.isOpen()) { |
|
|
|
if (channel != null && channel.isOpen()) { |
|
|
|
try { |
|
|
|
channel.close(); |
|
|
|
channel.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (IOException ignored) { |
|
|
|
catch (IOException ignored) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
// Various
|
|
|
|
// Various
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
@ -484,10 +472,7 @@ public abstract class DataBufferUtils { |
|
|
|
* @return {@code true} if the buffer was released; {@code false} otherwise. |
|
|
|
* @return {@code true} if the buffer was released; {@code false} otherwise. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static boolean release(@Nullable DataBuffer dataBuffer) { |
|
|
|
public static boolean release(@Nullable DataBuffer dataBuffer) { |
|
|
|
if (dataBuffer instanceof PooledDataBuffer) { |
|
|
|
return (dataBuffer instanceof PooledDataBuffer && ((PooledDataBuffer) dataBuffer).release()); |
|
|
|
return ((PooledDataBuffer) dataBuffer).release(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -520,8 +505,7 @@ public abstract class DataBufferUtils { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ReadableByteChannelGenerator |
|
|
|
private static class ReadableByteChannelGenerator implements Consumer<SynchronousSink<DataBuffer>> { |
|
|
|
implements Consumer<SynchronousSink<DataBuffer>> { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final ReadableByteChannel channel; |
|
|
|
private final ReadableByteChannel channel; |
|
|
|
|
|
|
|
|
|
|
|
@ -529,9 +513,8 @@ public abstract class DataBufferUtils { |
|
|
|
|
|
|
|
|
|
|
|
private final int bufferSize; |
|
|
|
private final int bufferSize; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public ReadableByteChannelGenerator( |
|
|
|
public ReadableByteChannelGenerator(ReadableByteChannel channel, |
|
|
|
ReadableByteChannel channel, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.channel = channel; |
|
|
|
this.channel = channel; |
|
|
|
this.dataBufferFactory = dataBufferFactory; |
|
|
|
this.dataBufferFactory = dataBufferFactory; |
|
|
|
@ -563,7 +546,6 @@ public abstract class DataBufferUtils { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -582,10 +564,9 @@ public abstract class DataBufferUtils { |
|
|
|
|
|
|
|
|
|
|
|
private final AtomicBoolean disposed = new AtomicBoolean(); |
|
|
|
private final AtomicBoolean disposed = new AtomicBoolean(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AsynchronousFileChannelReadCompletionHandler(AsynchronousFileChannel channel, |
|
|
|
|
|
|
|
FluxSink<DataBuffer> sink, long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
|
|
|
|
private AsynchronousFileChannelReadCompletionHandler( |
|
|
|
|
|
|
|
AsynchronousFileChannel channel, FluxSink<DataBuffer> sink, |
|
|
|
|
|
|
|
long position, DataBufferFactory dataBufferFactory, int bufferSize) { |
|
|
|
|
|
|
|
this.channel = channel; |
|
|
|
this.channel = channel; |
|
|
|
this.sink = sink; |
|
|
|
this.sink = sink; |
|
|
|
this.position = new AtomicLong(position); |
|
|
|
this.position = new AtomicLong(position); |
|
|
|
@ -599,10 +580,8 @@ public abstract class DataBufferUtils { |
|
|
|
long pos = this.position.addAndGet(read); |
|
|
|
long pos = this.position.addAndGet(read); |
|
|
|
dataBuffer.writePosition(read); |
|
|
|
dataBuffer.writePosition(read); |
|
|
|
this.sink.next(dataBuffer); |
|
|
|
this.sink.next(dataBuffer); |
|
|
|
|
|
|
|
|
|
|
|
if (!this.disposed.get()) { |
|
|
|
if (!this.disposed.get()) { |
|
|
|
DataBuffer newDataBuffer = |
|
|
|
DataBuffer newDataBuffer = this.dataBufferFactory.allocateBuffer(this.bufferSize); |
|
|
|
this.dataBufferFactory.allocateBuffer(this.bufferSize); |
|
|
|
|
|
|
|
ByteBuffer newByteBuffer = newDataBuffer.asByteBuffer(0, this.bufferSize); |
|
|
|
ByteBuffer newByteBuffer = newDataBuffer.asByteBuffer(0, this.bufferSize); |
|
|
|
this.channel.read(newByteBuffer, pos, newDataBuffer, this); |
|
|
|
this.channel.read(newByteBuffer, pos, newDataBuffer, this); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -618,12 +597,10 @@ public abstract class DataBufferUtils { |
|
|
|
release(dataBuffer); |
|
|
|
release(dataBuffer); |
|
|
|
this.sink.error(exc); |
|
|
|
this.sink.error(exc); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class AsynchronousFileChannelWriteCompletionHandler |
|
|
|
private static class AsynchronousFileChannelWriteCompletionHandler extends BaseSubscriber<DataBuffer> |
|
|
|
extends BaseSubscriber<DataBuffer> |
|
|
|
|
|
|
|
implements CompletionHandler<Integer, ByteBuffer> { |
|
|
|
implements CompletionHandler<Integer, ByteBuffer> { |
|
|
|
|
|
|
|
|
|
|
|
private final FluxSink<DataBuffer> sink; |
|
|
|
private final FluxSink<DataBuffer> sink; |
|
|
|
@ -639,6 +616,7 @@ public abstract class DataBufferUtils { |
|
|
|
|
|
|
|
|
|
|
|
public AsynchronousFileChannelWriteCompletionHandler( |
|
|
|
public AsynchronousFileChannelWriteCompletionHandler( |
|
|
|
FluxSink<DataBuffer> sink, AsynchronousFileChannel channel, long position) { |
|
|
|
FluxSink<DataBuffer> sink, AsynchronousFileChannel channel, long position) { |
|
|
|
|
|
|
|
|
|
|
|
this.sink = sink; |
|
|
|
this.sink = sink; |
|
|
|
this.channel = channel; |
|
|
|
this.channel = channel; |
|
|
|
this.position = new AtomicLong(position); |
|
|
|
this.position = new AtomicLong(position); |
|
|
|
@ -653,7 +631,6 @@ public abstract class DataBufferUtils { |
|
|
|
protected void hookOnNext(DataBuffer value) { |
|
|
|
protected void hookOnNext(DataBuffer value) { |
|
|
|
this.dataBuffer = value; |
|
|
|
this.dataBuffer = value; |
|
|
|
ByteBuffer byteBuffer = value.asByteBuffer(); |
|
|
|
ByteBuffer byteBuffer = value.asByteBuffer(); |
|
|
|
|
|
|
|
|
|
|
|
this.channel.write(byteBuffer, this.position.get(), byteBuffer, this); |
|
|
|
this.channel.write(byteBuffer, this.position.get(), byteBuffer, this); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -678,7 +655,6 @@ public abstract class DataBufferUtils { |
|
|
|
this.channel.write(byteBuffer, pos, byteBuffer, this); |
|
|
|
this.channel.write(byteBuffer, pos, byteBuffer, this); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.dataBuffer != null) { |
|
|
|
if (this.dataBuffer != null) { |
|
|
|
this.sink.next(this.dataBuffer); |
|
|
|
this.sink.next(this.dataBuffer); |
|
|
|
this.dataBuffer = null; |
|
|
|
this.dataBuffer = null; |
|
|
|
@ -696,4 +672,5 @@ public abstract class DataBufferUtils { |
|
|
|
this.sink.error(exc); |
|
|
|
this.sink.error(exc); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|