我正在制作有关数据压缩的项目(使用霍夫曼算法)。该项目仍在修订中。我遇到了一个非常有趣的问题。我需要从二进制文件中逐字节读取。我有这个文件FileInputHelper,它可以实现几种方法:
import java.io.IOException;
public class FileInputHelper implements Closeable {
private FileInputStream fileInputStream;
private BufferedReader fileBufferedReader;
public FileInputHelper(File file) throws IOException {
fileInputStream = new FileInputStream(file);
fileBufferedReader = new BufferedReader(
new InputStreamReader(fileInputStream));
}
public byte readByte() throws IOException {
return (byte)fileInputStream.read();
}
public char read() throws IOException {
return (char)fileInputStream.read();
}
public String readLine() throws IOException {
return fileBufferedReader.readLine();
}
@Override
public void close() throws IOException{
fileInputStream.close();
}
}
但是当二进制文件结束时,方法应返回-1。当然应该如此。但是有一些测试,其中有字节等于-1,但不是最后一个。 如您所知,这确实很关键。如果在中段我读到-1,我会认为文件已结束。但事实并非如此。有什么办法可以解决这个问题?我可以得到EOFException吗?如果我的代码不正确,我想听听您的建议。
答案 0 :(得分:1)
这就是InputStream.read()
在实际读取int
时声明返回类型byte
的原因。仅int
的低字节用于数据。如果您读取了-1
个字节,则它将返回255
,您必须手动将其强制转换为byte
。
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{1, 0, -1});
int read;
while ((read = in.read()) > -1) {
System.out.println("As int: " + read + ", as byte: " + (byte) read);
}
要输出:
As int: 1, as byte: 1
As int: 0, as byte: 0
As int: 255, as byte: -1
您可能不想在char
方法中使用public char read()
,因为char
是未签名的并且不能保存-1
。返回int
并遵循通常的约定更具可读性。
答案 1 :(得分:0)
问题在于List<BOMItemSummary> bomItems = new List<BOMItemSummary>();
...
var bomItemsForId = bom.BOMLineItems.Select(bomItem => new BOMItemSummary
{
...
});
bomItems.AddRange(bomItemsForId);
是未签名的,而char
是已签名的。基本上,哪里是一个特定字符(byte
),当转换为字节时它映射到0xffff
。这也是为什么InputStream上的-1
方法返回整数的原因,即使您正在获取字节或char。
处理此问题的一种方法是检查read()
是否返回read()
,然后再将其转换为字节或char。然后,如果-1
返回read()
,则可以引发EOFException并捕获该异常。例如
-1
但是,捕获异常并非旨在指示操作已正常完成。一种避免这种情况的处理方法是缓冲一个字符/字节,并添加一个int cur = fileInputStream.read();
if(cur == -1) {
throw new EOFException("End of input reached");
}else {
return (char) cur;
}
方法,如下所示。
available()
如果同时使用public class FileInputHelper implements Closeable {
private FileInputStream fileInputStream;
private BufferedReader fileBufferedReader;
private int next;
public FileInputHelper(File file) throws IOException {
fileInputStream = new FileInputStream(file);
fileBufferedReader = new BufferedReader(
new InputStreamReader(fileInputStream));
next = fileInputStream.read();
}
public byte readByte() throws IOException {
int cur = next;
next = fileInputStream.read();
if(cur == -1) {
throw new IOException("End of file reached");
}
return (byte) cur;
}
public char read() throws IOException {
int cur = next;
next = fileInputStream.read();
if(cur == -1) {
throw new IOException("End of file reached");
}
return (char) cur;
}
public String readLine() throws IOException {
return fileBufferedReader.readLine();
}
@Override
public void close() throws IOException{
fileInputStream.close();
}
// Returns true if there are more chars / bytes to read.
public boolean available() {
return next != -1;
}
}
/ read()
和readByte()
方法,这将对文件的读取产生影响,因此请记住这一点。