簡體   English   中英

如何反轉 Java 中的 InputStream?

[英]How to reverse a InputStream in Java?

假設我有一個輸入 stream 並且想要反轉它!

我類似的問題如何以相反的順序獲取輸入 stream 的內容? 但首先那是大約 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);
}

但我不確定這是最有效的方法!

即使對於大文件,我也希望有一種有效的方法來實現這一點!

如果您願意將整個文件讀入 memory,那么您的解決方案非常好。 memory 封裝可以通過反轉放置的內容而不是分配第二個數組來存儲反轉的內容來改進:

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等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM