我是Java的新手,我编写了一个适用于RandomAccessFile
的解析器(文件格式需要随机定位)。对于JUnit测试,我将不同的样本输入文件提供给解析器。
现在我认为在将解析器更改为从InputStream
读取之后(可以通过JUnit测试创建),我可以编写更简单的JUnit测试。
但是为了能够执行非测试用例,我必须创建(或更新)InputStream
来读取RandomAccessFile
当前指向的位置。 这可能吗?当然,解决方案应该既高效又优雅。
答案 0 :(得分:0)
由于没有人有更聪明的想法,这就是我所做的。遗憾的是,构造函数的非常有限的性质和super()
的使用以及Java中缺少多重继承使得实现变得更加困难并且比必要的更加丑陋。此外,invalidate()
的缓冲区缺少受保护的BufferedInputStream
,导致我猜测该怎么做(测试表明它有效):
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大小的特殊测试文件来测试定位和缓冲:更改位置后读取正确的数据(缓冲区似乎无效),并且读取的数据大小超过了所需的数据(即缓冲也有效。)