如何反转 Java 中的 InputStream?
How to reverse a InputStream in Java?
假设我有一个输入流并且想要反转它!
我有类似的问题 How to get the content of an input stream in reverse order? 但首先那是大约 8 岁,而且它不是我想要的!
假设我有一个像这样的 InputStream:
FileInputStream in = new FileInputStream(new File("some_random_file.bin"));
请注意,这不是专门针对文本文件,而是针对二进制文件!
现在,
我有办法逆转它:
public static InputStream reverseStream(InputStream in) throws Exception{
byte bytes[] = in.readAllBytes();
byte bytesRev[] = new byte[bytes.length];
for(int i=bytes.length - 1, j = 0;i >= 0; i--, j++)
bytesRev[i] = bytes[j];
return new ByteArrayInputStream(bytesRev);
}
但我不确定这是最有效的方法!
即使是大文件,我也希望有一种有效的方法来实现!
如果您愿意将整个文件读入内存,那么您的解决方案就很好。可以通过反转 placed 中的内容而不是分配第二个数组来存储反转的内容来改善内存占用:
public static InputStream reverseStream(InputStream in) throws Exception{
byte bytes[] = in.readAllBytes();
for(int i=bytes.length - 1, j = 0;i >j; i--, j++) {
byte tmp = bytes[i];
bytes[i] = bytes[j];
bytes[j] = tmp;
}
return new ByteArrayInputStream(bytes);
}
如果文件太大,不想一次全部加载,则需要使用class java.io.RandomAccessFile
倒序读取文件。您将需要使用某种内部缓冲来避免糟糕的性能。您可以将其包装在您自己的 InputStream
实现中,该实现通过缓冲区向后读取,并根据需要动态加载一个新的满缓冲区。
这是我对 class 的尝试。此代码完全未经测试(尽管可以编译)。
/**
* An input stream that reads a file in reverse. (UNTESTED)
*
* @author Ted Hopp
*/
class ReverseFileInputStream extends InputStream {
private final RandomAccessFile file;
/** Internal buffer for reading chunks of the file in reverse. */
private final byte[] buffer;
/** Position of the start of the buffer in the file. */
private long bufferPosition;
/** Position of the next byte to be read from the buffer. */
private int bufferCursor;
public ReverseFileInputStream(File file, int bufferSize) throws IOException {
this.file = new RandomAccessFile(file, "r");
buffer = new byte[bufferSize];
bufferPosition = this.file.length();
bufferCursor = -1;
}
@Override public int read() throws IOException {
if (bufferCursor < 0) {
fillBuffer();
}
return bufferCursor < 0 ? -1 : (buffer[bufferCursor--] & 0xff);
}
@Override public void close() throws IOException {
file.close();
}
private void fillBuffer() throws IOException {
if (bufferPosition > 0) {
long newBufferPosition = Math.max(0L, bufferPosition - buffer.length);
bufferCursor = (int) (bufferPosition - newBufferPosition);
file.seek(newBufferPosition);
file.readFully(buffer, 0, bufferCursor--);
bufferPosition = newBufferPosition;
}
}
}
请注意,如果您尝试将 Reader
包裹起来,除非基础文件的文本编码是每个字符一个字节,否则结果可能是无意义的。同样 DataInputStream
,等等
假设我有一个输入流并且想要反转它!
我有类似的问题 How to get the content of an input stream in reverse order? 但首先那是大约 8 岁,而且它不是我想要的!
假设我有一个像这样的 InputStream:
FileInputStream in = new FileInputStream(new File("some_random_file.bin"));
请注意,这不是专门针对文本文件,而是针对二进制文件!
现在,
我有办法逆转它:
public static InputStream reverseStream(InputStream in) throws Exception{
byte bytes[] = in.readAllBytes();
byte bytesRev[] = new byte[bytes.length];
for(int i=bytes.length - 1, j = 0;i >= 0; i--, j++)
bytesRev[i] = bytes[j];
return new ByteArrayInputStream(bytesRev);
}
但我不确定这是最有效的方法!
即使是大文件,我也希望有一种有效的方法来实现!
如果您愿意将整个文件读入内存,那么您的解决方案就很好。可以通过反转 placed 中的内容而不是分配第二个数组来存储反转的内容来改善内存占用:
public static InputStream reverseStream(InputStream in) throws Exception{
byte bytes[] = in.readAllBytes();
for(int i=bytes.length - 1, j = 0;i >j; i--, j++) {
byte tmp = bytes[i];
bytes[i] = bytes[j];
bytes[j] = tmp;
}
return new ByteArrayInputStream(bytes);
}
如果文件太大,不想一次全部加载,则需要使用class java.io.RandomAccessFile
倒序读取文件。您将需要使用某种内部缓冲来避免糟糕的性能。您可以将其包装在您自己的 InputStream
实现中,该实现通过缓冲区向后读取,并根据需要动态加载一个新的满缓冲区。
这是我对 class 的尝试。此代码完全未经测试(尽管可以编译)。
/**
* An input stream that reads a file in reverse. (UNTESTED)
*
* @author Ted Hopp
*/
class ReverseFileInputStream extends InputStream {
private final RandomAccessFile file;
/** Internal buffer for reading chunks of the file in reverse. */
private final byte[] buffer;
/** Position of the start of the buffer in the file. */
private long bufferPosition;
/** Position of the next byte to be read from the buffer. */
private int bufferCursor;
public ReverseFileInputStream(File file, int bufferSize) throws IOException {
this.file = new RandomAccessFile(file, "r");
buffer = new byte[bufferSize];
bufferPosition = this.file.length();
bufferCursor = -1;
}
@Override public int read() throws IOException {
if (bufferCursor < 0) {
fillBuffer();
}
return bufferCursor < 0 ? -1 : (buffer[bufferCursor--] & 0xff);
}
@Override public void close() throws IOException {
file.close();
}
private void fillBuffer() throws IOException {
if (bufferPosition > 0) {
long newBufferPosition = Math.max(0L, bufferPosition - buffer.length);
bufferCursor = (int) (bufferPosition - newBufferPosition);
file.seek(newBufferPosition);
file.readFully(buffer, 0, bufferCursor--);
bufferPosition = newBufferPosition;
}
}
}
请注意,如果您尝试将 Reader
包裹起来,除非基础文件的文本编码是每个字符一个字节,否则结果可能是无意义的。同样 DataInputStream
,等等