ByteIOOperator.java
package space.sunqian.fs.io;
import space.sunqian.annotation.Nonnull;
import space.sunqian.annotation.Nullable;
import space.sunqian.annotation.ThreadSafe;
import space.sunqian.fs.base.chars.CharsKit;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
/**
* This interface provides I/O operations for byte.
*
* @author sunqian
*/
@ThreadSafe
public interface ByteIOOperator {
/**
* Returns the buffer size for I/O operations.
*
* @return the buffer size for I/O operations
*/
int bufferSize();
/**
* Reads all data from the input stream into a new array, continuing until reaches the end of the input stream, and
* returns the array.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code null}.
*
* @param src the input stream
* @return a new array containing the read data, or {@code null} if reaches the end of the input stream and no data
* is read
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] read(@Nonnull InputStream src) throws IORuntimeException {
return IOKit.read0(src, bufferSize(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the input stream into a new array, and returns the array. If the specified
* length is {@code 0}, returns an empty array without reading. Otherwise, this method keeps reading until the read
* number reaches the specified length or reaches the end of the input stream.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code null}.
* <p>
* Note this method will allocate a new array with the specified length, and the excessive length may cause out of
* memory.
*
* @param src the input stream
* @param len the specified read length, must {@code >= 0}
* @return a new array containing the read data, or {@code null} if reaches the end of the input stream and no data
* is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] read(
@Nonnull InputStream src, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.read0(src, len, bufferSize(), IOChecker.endChecker());
}
/**
* Reads all data from the source channel into a new buffer, continuing until reaches the end of the source channel,
* and returns the buffer. The new buffer's position is {@code 0} and limit equals its capacity.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
*
* @param src the source channel
* @return a new buffer containing the read data, or {@code null} if reaches the end of the source channel and no
* data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable ByteBuffer read(@Nonnull ReadableByteChannel src) throws IORuntimeException {
return IOKit.read0(src, bufferSize(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the source channel into a new buffer, and returns the buffer. If the
* specified length is {@code 0}, returns an empty buffer without reading. Otherwise, this method keeps reading
* until the read number reaches the specified length or reaches the end of the source channel. The new buffer's
* position is {@code 0} and limit equals its capacity.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
* <p>
* Note this method will allocate a new array with the specified length, and the excessive length may cause out of
* memory.
*
* @param src the source channel
* @param len the specified read length, must {@code >= 0}
* @return a new buffer containing the read data, or {@code null} if reaches the end of the source channel and no
* data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable ByteBuffer read(
@Nonnull ReadableByteChannel src, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.read0(src, len, bufferSize(), IOChecker.endChecker());
}
/**
* Reads all data from the source channel into a new array, continuing until reaches the end of the source channel,
* and returns the array.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
*
* @param src the source channel
* @return a new array containing the read data, or {@code null} if reaches the end of the source channel and no
* data is read
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] readBytes(@Nonnull ReadableByteChannel src) throws IORuntimeException {
ByteBuffer buf = read(src);
return buf == null ? null : BufferKit.read(buf);
}
/**
* Reads a specified length of data from the source channel into a new array, and returns the array. If the
* specified length is {@code 0}, returns an empty array without reading. Otherwise, this method keeps reading until
* the read number reaches the specified length or reaches the end of the source channel.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
* <p>
* Note this method will allocate a new array with the specified length, and the excessive length may cause out of
* memory.
*
* @param src the source channel
* @param len the specified read length, must {@code >= 0}
* @return a new array containing the read data, or {@code null} if reaches the end of the source channel and no
* data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] readBytes(
@Nonnull ReadableByteChannel src, int len
) throws IllegalArgumentException, IORuntimeException {
ByteBuffer buf = read(src, len);
return buf == null ? null : BufferKit.read(buf);
}
/**
* Reads data from the input stream into the output stream, until reaches the end of the input stream, and returns
* the actual number of bytes read to.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output stream
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(@Nonnull InputStream src, @Nonnull OutputStream dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the input stream into the output stream, until the read number reaches the
* specified length or reaches the end of the input stream, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the input stream
* and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output stream
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(
@Nonnull InputStream src, @Nonnull OutputStream dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.endChecker());
}
/**
* Reads data from the input stream into the output channel, until reaches the end of the input stream, and returns
* the actual number of bytes read to.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output channel
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(@Nonnull InputStream src, @Nonnull WritableByteChannel dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the input stream into the output channel, until the read number reaches the
* specified length or reaches the end of the input stream, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the input stream
* and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output channel
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(
@Nonnull InputStream src, @Nonnull WritableByteChannel dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.endChecker());
}
/**
* Reads data from the input stream into the destination array, until the read number reaches the array's length or
* reaches the end of the input stream, and returns the actual number of bytes read to.
* <p>
* If the array's length is {@code 0}, returns {@code 0} without reading. If reaches the end of the input stream and
* no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the destination array
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(@Nonnull InputStream src, byte @Nonnull [] dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, 0, dst.length, IOChecker.endChecker());
}
/**
* Reads a specified length of data from the input stream into the destination array, starting at the specified
* offset, until the read number reaches the specified length or reaches the end of the input stream, and returns
* the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading. If reaches the end of the input stream
* and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the destination array
* @param off the specified offset of the array
* @param len the specified length to read
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IndexOutOfBoundsException if the arguments are out of bounds
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(
@Nonnull InputStream src, byte @Nonnull [] dst, int off, int len
) throws IndexOutOfBoundsException, IORuntimeException {
IOChecker.checkOffLen(off, len, dst.length);
return IOKit.readTo0(src, dst, off, len, IOChecker.endChecker());
}
/**
* Reads data from the input stream into the destination buffer, until reaches the end of the stream or buffer, and
* returns the actual number of bytes read to.
* <p>
* If the destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if reaches the end of the
* input stream and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the input stream
* @param dst the destination buffer
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(@Nonnull InputStream src, @Nonnull ByteBuffer dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, dst.remaining(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the input stream into the destination buffer, until the read number reaches
* the specified length or reaches the end of the stream or buffer, and returns the actual number of bytes read to.
* <p>
* If the specified length or destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if
* reaches the end of the input stream and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the input stream
* @param dst the specified buffer
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input stream and no data is
* read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(
@Nonnull InputStream src, @Nonnull ByteBuffer dst, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, IOChecker.endChecker());
}
/**
* Reads data from the input channel into the output stream, until reaches the end of the input channel, and returns
* the actual number of bytes read to.
* <p>
* If reaches the end of the input channel and no data is read, returns {@code -1}.
*
* @param src the input channel
* @param dst the output stream
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input channel and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(@Nonnull ReadableByteChannel src, @Nonnull OutputStream dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the input channel into the output stream, until the read number reaches the
* specified length or reaches the end of the input channel, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the input channel
* and no data is read, returns {@code -1}.
*
* @param src the input channel
* @param dst the output stream
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the input channel and no data is
* read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(
@Nonnull ReadableByteChannel src, @Nonnull OutputStream dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.endChecker());
}
/**
* Reads data from the source channel into the destination channel, until reaches the end of the source channel, and
* returns the actual number of bytes read to.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination channel
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the source channel and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(@Nonnull ReadableByteChannel src, @Nonnull WritableByteChannel dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.endChecker());
}
/**
* Reads a specified length of data from the source channel into the destination channel, until the read number
* reaches the specified length or reaches the end of the source channel, returns the actual number of bytes read
* to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the source channel
* and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination channel
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the source channel and no data is
* read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long readTo(
@Nonnull ReadableByteChannel src, @Nonnull WritableByteChannel dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.endChecker());
}
/**
* Reads data from the source channel into the destination array, until the read number reaches the array's length
* or reaches the end of the source channel, and returns the actual number of bytes read to.
* <p>
* If the array's length is {@code 0}, returns {@code 0} without reading. If reaches the end of the source channel
* and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination array
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the source channel and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(@Nonnull ReadableByteChannel src, byte @Nonnull [] dst) throws IORuntimeException {
return readTo(src, ByteBuffer.wrap(dst));
}
/**
* Reads a specified length of data from the source channel into the destination array, starting at the specified
* offset, until the read number reaches the specified length or reaches the end of the source channel, and returns
* the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading. If reaches the end of the source channel
* and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination array
* @param off the specified offset of the array
* @param len the specified length to read
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the source channel and no data is
* read
* @throws IndexOutOfBoundsException if the arguments are out of bounds
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(
@Nonnull ReadableByteChannel src, byte @Nonnull [] dst, int off, int len
) throws IndexOutOfBoundsException, IORuntimeException {
ByteBuffer buf = ByteBuffer.wrap(dst, off, len);
return readTo(src, buf);
}
/**
* Reads data from the source channel into the destination buffer, until reaches the end of the stream or buffer,
* and returns the actual number of bytes read to.
* <p>
* If the destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if reaches the end of the
* source channel and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the source channel
* @param dst the destination buffer
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the source channel and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(@Nonnull ReadableByteChannel src, @Nonnull ByteBuffer dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, IOChecker.endChecker());
}
/**
* Reads a specified length of data from the source channel into the destination buffer, until the read number
* reaches the specified length or reaches the end of the stream or buffer, and returns the actual number of bytes
* read to.
* <p>
* If the specified length or destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if
* reaches the end of the source channel and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the source channel
* @param dst the specified buffer
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, or {@code -1} if reaches the end of the source channel and no data is
* read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default int readTo(
@Nonnull ReadableByteChannel src, @Nonnull ByteBuffer dst, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, IOChecker.endChecker());
}
/**
* Reads all data from the input stream as a string with {@link CharsKit#defaultCharset()}, continuing until reaches
* the end of the stream, and returns the string.
* <p>
* If reaches the end of the stream and no data is read, returns {@code null}.
*
* @param src the input stream
* @return a string with {@link CharsKit#defaultCharset()}, or {@code null} if reaches the end of the stream and no
* data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String string(@Nonnull InputStream src) throws IORuntimeException {
return string(src, CharsKit.defaultCharset());
}
/**
* Reads all data from the input stream as a string with the specified charset, continuing until reaches the end of
* the stream, and returns the string.
* <p>
* If reaches the end of the stream and no data is read, returns {@code null}.
*
* @param src the input stream
* @param charset the specified charset
* @return a string with the specified charset, or {@code null} if reaches the end of the stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String string(
@Nonnull InputStream src, @Nonnull Charset charset
) throws IORuntimeException {
byte[] bytes = read(src);
return bytes == null ? null : new String(bytes, charset);
}
/**
* Reads all data from the channel as a string with {@link CharsKit#defaultCharset()}, continuing until reaches the
* end of the channel, and returns the string.
* <p>
* If reaches the end of the channel and no data is read, returns {@code null}.
*
* @param src the channel
* @return a string with {@link CharsKit#defaultCharset()}, or {@code null} if reaches the end of the channel and no
* data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String string(@Nonnull ReadableByteChannel src) throws IORuntimeException {
return string(src, CharsKit.defaultCharset());
}
/**
* Reads all data from the channel as a string with the specified charset, continuing until reaches the end of the
* channel, and returns the string.
* <p>
* If reaches the end of the channel and no data is read, returns {@code null}.
*
* @param src the channel
* @param charset the specified charset
* @return a string with the specified charset, or {@code null} if reaches the end of the channel and no data is
* read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String string(
@Nonnull ReadableByteChannel src, @Nonnull Charset charset
) throws IORuntimeException {
ByteBuffer bytes = read(src);
return bytes == null ? null : BufferKit.string(bytes, charset);
}
/**
* Reads available data from the input stream into a new array, continuing until no data is immediately available,
* and returns the array.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code null}.
*
* @param src the input stream
* @return a new array containing the read data, possibly empty, or {@code null} if reaches the end of the input
* stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] available(@Nonnull InputStream src) throws IORuntimeException {
return IOKit.read0(src, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the input stream into a new array, and returns the array. If the specified
* length is {@code 0}, returns an empty array without reading. Otherwise, this method keeps reading until the read
* number reaches the specified length or no data is immediately available.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code null}.
* <p>
* Note this method will allocate a new array with the specified length, and the excessive length may cause out of
* memory.
*
* @param src the input stream
* @param len the specified read length, must {@code >= 0}
* @return a new array containing the read data, possibly empty, or {@code null} if reaches the end of the input
* stream and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] available(
@Nonnull InputStream src, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.read0(src, len, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads available data from the source channel into a new buffer, continuing until no data is immediately
* available, and returns the buffer. The new buffer's position is {@code 0} and limit equals its capacity.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
*
* @param src the source channel
* @return a new buffer containing the read data, possibly empty, or {@code null} if reaches the end of the source
* channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable ByteBuffer available(@Nonnull ReadableByteChannel src) throws IORuntimeException {
return IOKit.read0(src, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the source channel into a new buffer, and returns the buffer. If the
* specified length is {@code 0}, returns an empty buffer without reading. Otherwise, this method keeps reading
* until the read number reaches the specified length or no data is immediately available. The new buffer's position
* is {@code 0} and limit equals its capacity.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
* <p>
* Note this method will allocate a new buffer with the specified length, and the excessive length may cause out of
* memory.
*
* @param src the source channel
* @param len the specified read length, must {@code >= 0}
* @return a new buffer containing the read data, possibly empty, or {@code null} if reaches the end of the source
* channel and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable ByteBuffer available(
@Nonnull ReadableByteChannel src, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.read0(src, len, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads available data from the source channel into a new array, continuing until no data is immediately available,
* and returns the array.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
*
* @param src the source channel
* @return a new array containing the read data, possibly empty, or {@code null} if reaches the end of the source
* channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] availableBytes(@Nonnull ReadableByteChannel src) throws IORuntimeException {
ByteBuffer bytes = available(src);
if (bytes == null) {
return null;
}
if (!bytes.hasRemaining()) {
return new byte[0];
}
return BufferKit.read(bytes);
}
/**
* Reads a specified length of data from the source channel into a new array, and returns the array. If the
* specified length is {@code 0}, returns an empty array without reading. Otherwise, this method keeps reading until
* the read number reaches the specified length or no data is immediately available.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code null}.
* <p>
* Note this method will allocate a new array with the specified length, and the excessive length may cause out of
* memory.
*
* @param src the source channel
* @param len the specified read length, must {@code >= 0}
* @return a new array containing the read data, possibly empty, or {@code null} if reaches the end of the source
* channel and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default byte @Nullable [] availableBytes(
@Nonnull ReadableByteChannel src, int len
) throws IllegalArgumentException, IORuntimeException {
ByteBuffer bytes = available(src, len);
if (bytes == null) {
return null;
}
if (!bytes.hasRemaining()) {
return new byte[0];
}
return BufferKit.read(bytes);
}
/**
* Reads available data from the input stream into the output stream, until no data is immediately available, and
* returns the actual number of bytes read to.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output stream
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(@Nonnull InputStream src, @Nonnull OutputStream dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the input stream into the output stream, until the read number reaches the
* specified length or no data is immediately available, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the input stream
* and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output stream
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(
@Nonnull InputStream src, @Nonnull OutputStream dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads available data from the input stream into the output channel, until no data is immediately available, and
* returns the actual number of bytes read to.
* <p>
* If reaches the end of the input stream and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output channel
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(@Nonnull InputStream src, @Nonnull WritableByteChannel dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the input stream into the output channel, until the read number reaches the
* specified length or no data is immediately available, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the input stream
* and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the output channel
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(
@Nonnull InputStream src, @Nonnull WritableByteChannel dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads available data from the input stream into the destination array, until the read number reaches the array's
* length or no data is immediately available, and returns the actual number of bytes read to.
* <p>
* If the array's length is {@code 0}, returns {@code 0} without reading. If reaches the end of the input stream and
* no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the destination array
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(@Nonnull InputStream src, byte @Nonnull [] dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, 0, dst.length, IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the input stream into the destination array, starting at the specified
* offset, until the read number reaches the specified length or no data is immediately available, and returns the
* actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading. If reaches the end of the input stream
* and no data is read, returns {@code -1}.
*
* @param src the input stream
* @param dst the destination array
* @param off the specified offset of the array
* @param len the specified length to read
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IndexOutOfBoundsException if the arguments are out of bounds
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(
@Nonnull InputStream src, byte @Nonnull [] dst, int off, int len
) throws IndexOutOfBoundsException, IORuntimeException {
IOChecker.checkOffLen(off, len, dst.length);
return IOKit.readTo0(src, dst, off, len, IOChecker.availableChecker());
}
/**
* Reads available data from the input stream into the destination buffer, until reaches the end of the buffer or no
* data is immediately available, and returns the actual number of bytes read to.
* <p>
* If the destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if reaches the end of the
* input stream and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the input stream
* @param dst the destination buffer
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(@Nonnull InputStream src, @Nonnull ByteBuffer dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, dst.remaining(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the input stream into the destination buffer, until the read number reaches
* the specified length or reaches the end of the buffer or no data is immediately available, and returns the actual
* number of bytes read to.
* <p>
* If the specified length or destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if
* reaches the end of the input stream and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the input stream
* @param dst the specified buffer
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* stream and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(
@Nonnull InputStream src, @Nonnull ByteBuffer dst, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, IOChecker.availableChecker());
}
/**
* Reads available data from the input channel into the output stream, until no data is immediately available, and
* returns the actual number of bytes read to.
* <p>
* If reaches the end of the input channel and no data is read, returns {@code -1}.
*
* @param src the input channel
* @param dst the output stream
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(@Nonnull ReadableByteChannel src, @Nonnull OutputStream dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the input channel into the output stream, until the read number reaches the
* specified length or no data is immediately available, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the input channel
* and no data is read, returns {@code -1}.
*
* @param src the input channel
* @param dst the output stream
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the input
* channel and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(
@Nonnull ReadableByteChannel src, @Nonnull OutputStream dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads available data from the source channel into the destination channel, until no data is immediately
* available, and returns the actual number of bytes read to.
* <p>
* If reaches the end of the source channel and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination channel
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the source
* channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(@Nonnull ReadableByteChannel src, @Nonnull WritableByteChannel dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the source channel into the destination channel, until the read number
* reaches the specified length or no data is immediately available, returns the actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading; if reaches the end of the source channel
* and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination channel
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the source
* channel and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default long availableTo(
@Nonnull ReadableByteChannel src, @Nonnull WritableByteChannel dst, long len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, bufferSize(), IOChecker.availableChecker());
}
/**
* Reads available data from the source channel into the destination array, until the read number reaches the
* array's length or no data is immediately available, and returns the actual number of bytes read to.
* <p>
* If the array's length is {@code 0}, returns {@code 0} without reading. If reaches the end of the source channel
* and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination array
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the source
* channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(@Nonnull ReadableByteChannel src, byte @Nonnull [] dst) throws IORuntimeException {
return availableTo(src, ByteBuffer.wrap(dst));
}
/**
* Reads a specified length of data from the source channel into the destination array, starting at the specified
* offset, until the read number reaches the specified length or no data is immediately available, and returns the
* actual number of bytes read to.
* <p>
* If the specified length is {@code 0}, returns {@code 0} without reading. If reaches the end of the source channel
* and no data is read, returns {@code -1}.
*
* @param src the source channel
* @param dst the destination array
* @param off the specified offset of the array
* @param len the specified length to read
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the source
* channel and no data is read
* @throws IndexOutOfBoundsException if the arguments are out of bounds
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(
@Nonnull ReadableByteChannel src, byte @Nonnull [] dst, int off, int len
) throws IndexOutOfBoundsException, IORuntimeException {
ByteBuffer buf = ByteBuffer.wrap(dst, off, len);
return availableTo(src, buf);
}
/**
* Reads available data from the source channel into the destination buffer, until reaches the end of the buffer or
* no data is immediately available, and returns the actual number of bytes read to.
* <p>
* If the destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if reaches the end of the
* source channel and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the source channel
* @param dst the destination buffer
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the source
* channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(@Nonnull ReadableByteChannel src, @Nonnull ByteBuffer dst) throws IORuntimeException {
return IOKit.readTo0(src, dst, IOChecker.availableChecker());
}
/**
* Reads a specified length of data from the source channel into the destination buffer, until the read number
* reaches the specified length or reaches the end of the buffer or no data is immediately available, and returns
* the actual number of bytes read to.
* <p>
* If the specified length or destination buffer's remaining is {@code 0}, returns {@code 0} without reading; if
* reaches the end of the source channel and no data is read, returns {@code -1}.
* <p>
* The buffer's position increments by the actual read number.
*
* @param src the source channel
* @param dst the specified buffer
* @param len the specified length, must {@code >= 0}
* @return the actual number of bytes read to, possibly {@code 0}, or {@code -1} if reaches the end of the source
* channel and no data is read
* @throws IllegalArgumentException if the specified read length is illegal
* @throws IORuntimeException if an I/O error occurs
*/
default int availableTo(
@Nonnull ReadableByteChannel src, @Nonnull ByteBuffer dst, int len
) throws IllegalArgumentException, IORuntimeException {
IOChecker.checkLen(len);
return IOKit.readTo0(src, dst, len, IOChecker.availableChecker());
}
/**
* Reads available data from the input stream as a string with {@link CharsKit#defaultCharset()}, continuing until
* no data is immediately available, and returns the string.
* <p>
* If reaches the end of the stream and no data is read, returns {@code null}.
*
* @param src the input stream
* @return a string with {@link CharsKit#defaultCharset()}, possibly empty, or {@code null} if reaches the end of
* the stream and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String availableString(@Nonnull InputStream src) throws IORuntimeException {
return availableString(src, CharsKit.defaultCharset());
}
/**
* Reads available data from the input stream as a string with the specified charset, continuing until no data is
* immediately available, and returns the string.
* <p>
* If reaches the end of the stream and no data is read, returns {@code null}.
*
* @param src the input stream
* @param charset the specified charset
* @return a string with the specified charset, possibly empty, or {@code null} if reaches the end of the stream and
* no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String availableString(
@Nonnull InputStream src, @Nonnull Charset charset
) throws IORuntimeException {
byte[] bytes = available(src);
return bytes == null ? null : new String(bytes, charset);
}
/**
* Reads available data from the channel as a string with {@link CharsKit#defaultCharset()}, continuing until no
* data is immediately available, and returns the string.
* <p>
* If reaches the end of the channel and no data is read, returns {@code null}.
*
* @param src the channel
* @return a string with {@link CharsKit#defaultCharset()}, possibly empty, or {@code null} if reaches the end of
* the channel and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String availableString(@Nonnull ReadableByteChannel src) throws IORuntimeException {
return availableString(src, CharsKit.defaultCharset());
}
/**
* Reads available data from the channel as a string with the specified charset, continuing until no data is
* immediately available, and returns the string.
* <p>
* If reaches the end of the channel and no data is read, returns {@code null}.
*
* @param src the channel
* @param charset the specified charset
* @return a string with the specified charset, possibly empty, or {@code null} if reaches the end of the channel
* and no data is read
* @throws IORuntimeException if an I/O error occurs
*/
default @Nullable String availableString(
@Nonnull ReadableByteChannel src, @Nonnull Charset charset
) throws IORuntimeException {
ByteBuffer bytes = available(src);
if (bytes == null) {
return null;
}
if (!bytes.hasRemaining()) {
return "";
}
return BufferKit.string(bytes, charset);
}
}