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