簡體   English   中英

如何將InputStream用於RandomAccessFile的一部分?

[英]How can I use an InputStream for parts of a RandomAccessFile?

我是Java的新手,我寫了一個對RandomAccessFile起作用的解析器(文件格式需要隨機定位)。 對於JUnit測試,我將不同的示例輸入文件輸入解析器。

現在,我認為將解析器改為從InputStream讀取(由JUnit測試創建)后,可以編寫更簡單的JUnit測試。

但是為了能夠執行非測試用例,我必須創建(或更新) InputStream來讀取RandomAccessFile當前指向的位置。 那可能嗎? 當然,解決方案應該既高效又優雅。

沒有人有一個更聰明的主意,這就是我所做的。 不幸的是,構造函數的性質非常受限制,而且super()的使用以及Java中缺少多重繼承的情況使實現變得比必要的困難和丑陋。 另外,由於BufferedInputStream的緩沖區缺少受保護的invalidate() ,這引起了我的猜測(測試表明它可以正常工作):

package de.whatever.uw.utils;

import java.io.BufferedInputStream;

/**
 * @author U. Windl
 */
public class RandomAccessFileInputStream extends BufferedInputStream {

    private RandomAccessFile file;  // file to use

   /**
     * Constructor
     * @param fileName File to open for reading
     * @throws FileNotFoundException 
     */
    public RandomAccessFileInputStream(String fileName) throws FileNotFoundException {
        super(System.in);   // dummy to work around Java's inflexibility
        assert fileName != null;
        file = new RandomAccessFile(fileName, "r");
        FileChannel channel = file.getChannel();
        in = new BufferedInputStream(Channels.newInputStream(channel));
        assert file != null;
    }

    /**
     * Forbidden Constructor
     * @param in Input stream
     */
    private RandomAccessFileInputStream(InputStream in) {
        super(in);
    }

    /**
     * Forbidden Constructor
     * @param in
     * @param size
     */
    private RandomAccessFileInputStream(InputStream in, int size) {
        super(in, size);
    }

    /* (non-Javadoc)
     * @see java.io.BufferedInputStream#close()
     */
    public void close() throws IOException {
        super.close();
        file.close();
    }

    /**
     * @return Current offset in stream
     * @throws IOException
     */
    public long getFilePointer() throws IOException {
        return file.getFilePointer();
    }

    /**
     * @return
     * @throws IOException
     * @see java.io.RandomAccessFile#length()
     */
    public long length() throws IOException {
        return file.length();
    }

    /**
     * @param pos New stream position
     * @throws IOException
     */
    public void seek(long pos) throws IOException {
        file.seek(pos);
        pos = count = 0;    // invalidate stream buffer
    }

    // other methods are inherited without change (and I really use a very few of them actually)
}

(我創建了一個大約8kB大小的特殊測試文件來測試定位和緩沖:更改位置后,讀取了正確的數據(使緩沖區無效),並且讀取了超出請求的數據大小(即緩沖也起作用) )。

暫無
暫無

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

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