Java 如何将InputStream用于RandomAccessFile的某些部分?

Java 如何将InputStream用于RandomAccessFile的某些部分?,java,inputstream,randomaccessfile,Java,Inputstream,Randomaccessfile,我是Java新手,我编写了一个解析器,可以处理RandomAccessFile(文件格式需要随机定位)。对于JUnit测试,我将不同的示例输入文件提供给解析器 现在我想,在将解析器改为从InputStream读取(这将由JUnit测试创建)之后,我可以编写更简单的JUnit测试 但是为了能够执行非测试用例,我必须创建(或更新)一个InputStream来读取RandomAccessFile当前指向的位置。可能吗?当然,解决方案应该既高效又优雅。因为没有人有比这更聪明的想法,所以我就是这么做的。不

我是Java新手,我编写了一个解析器,可以处理
RandomAccessFile
(文件格式需要随机定位)。对于JUnit测试,我将不同的示例输入文件提供给解析器

现在我想,在将解析器改为从
InputStream
读取(这将由JUnit测试创建)之后,我可以编写更简单的JUnit测试


但是为了能够执行非测试用例,我必须创建(或更新)一个
InputStream
来读取
RandomAccessFile
当前指向的位置。可能吗?当然,解决方案应该既高效又优雅。

因为没有人有比这更聪明的想法,所以我就是这么做的。不幸的是,构造函数的性质非常有限,使用了
super()
,而且Java中缺少多重继承,这使得实现变得比必要的更困难、更丑陋。另外,
BufferedInputStream
的缓冲区缺少受保护的
invalidate()
,这让我猜怎么做(测试表明它可以工作):


(我创建了一个大小约为8kB的特殊测试文件来测试定位和缓冲:在位置更改后,读取正确的数据(使缓冲区无效似乎起作用),并读取超过请求的数据大小(即缓冲也起作用)。)

如果你展示一些代码,可能会更容易帮助你。@Andy Turner:打开
RandomAcessFile
的代码,从这样的文件读取的代码,或者从
输入流读取的(尚未存在)代码
?或者你到底在寻找什么?从我的想法中,我得到了一个
seekablybytechnel
通道的概念。newInputStream()
听起来像是一个可能的解决方案,但没有缓冲。阅读
InputStream
的描述(
BufferedInputStream
)我想知道是否最容易实现一个新类,将其委托给
RandomAccessFile
,添加
setPosition()
(并在
BufferedInputStream
的情况下使位置canges上的缓冲区无效)。谢谢,这正是我今天需要的!
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)
}