我查看了一些关于二进制文件的先前线程,我正在按照它说的做DataStream,但我不确定为什么我的工作并不正常,因为我认为我做的事与线程说我是一样的。我的目标是创建一个方法,该文件名采用.bin格式的文件名和移位整数。我将创建一个.bin类型的新文件,其中字符已移位。只会移动大写字母或小写字母。我不知道正在读入的二进制文件的长度,并且需要遍历所有字符。该文件只有1行。我有一个方法,它给我该行上的字符数和一个创建文件的方法。我知道的程序确实正确地创建了文件。无论如何,正在发生的是创建文件,然后给我一个关于该行的EOF异常:char currentChar = data.readChar();
这是我的代码:
private static void cipherShifter(String file, int shift) {
String newFile=file+"_cipher";
createFile(newFile);
int numChar;
try {
FileInputStream stream=new FileInputStream(file);
DataInputStream data=new DataInputStream(stream);
FileOutputStream streamOut=new FileOutputStream(newFile);
DataOutputStream dataOut=new DataOutputStream(streamOut);
numChar=readAllInts(data);
for (int i=0;i<numChar;++i) {
char currentChar=data.readChar();
if (((currentChar>='A')&&(currentChar<='Z'))||((currentChar>='a')&&(currentChar<='z'))) {
currentChar=currentChar+=shift;
dataOut.writeChar(currentChar);
}
else {
dataOut.writeChar(currentChar);
}
}
data.close();
dataOut.flush();
dataOut.close();
} catch(IOException error) {
error.printStackTrace();
}
}
private static void createFile(String fileName) {
File file=new File(fileName);
if (file.exists()) {
//Do nothing
}
else {
try {
file.createNewFile();
} catch (IOException e) {
//Do nothing
}
}
}
private static int readAllInts(DataInputStream din) throws IOException {
int count = 0;
while (true) {
try {
din.readInt(); ++count;
} catch (EOFException e) {
return count;
}
}
}
所以我认为不应该发生错误,因为我确实有正确的数据类型,我告诉它只读一个字符。任何帮助都会很棒。提前谢谢。
答案 0 :(得分:2)
根据上面的描述,您的错误将在data.readChar()方法调用中报告,而不是在readAllInts方法中报告。我模拟了错误附近的代码,并在同一位置的文本文件中获得了相同的异常。
我使用readByte方法一次读取一个字节,因为您主要对ASCII字节感兴趣。我还将readAllInts更改为readAllBytes,因此我使用总字节数。
private static void cipherShifter(String file, int shift) {
String newFile=file+"_cipher";
createFile(newFile);
int numChar;
try {
FileInputStream stream=new FileInputStream(file);
DataInputStream data=new DataInputStream(stream);
FileOutputStream streamOut=new FileOutputStream(newFile);
DataOutputStream dataOut=new DataOutputStream(streamOut);
numBytes=readAllBytes(data);
stream.close();
data.close();
stream=new FileInputStream(file);
data=new DataInputStream(stream);
for (int i=0;i<numBytes;++i) {
byte currentByte=data.readByte();
if (((currentByte>=65)&&(currentByte<=90))||((currentByte>=97)&&(currentByte<=122))) {
currentByte=currentByte+=shift; //need to ensure no overflow beyond a byte
dataOut.writeByte(currentByte);
}
else {
dataOut.writeByte(currentByte);
}
}
data.close();
dataOut.flush();
dataOut.close();
} catch(IOException error) {
error.printStackTrace();
}
}
private static void createFile(String fileName) {
File file=new File(fileName);
if (file.exists()) {
//Do nothing
}
else {
try {
file.createNewFile();
} catch (IOException e) {
//Do nothing
}
}
}
private static int readAllBytes(DataInputStream din) throws IOException {
int count = 0;
while (true) {
try {
din.readByte(); ++count;
} catch (EOFException e) {
return count;
}
}
}
答案 1 :(得分:1)
看起来你正在获得EOFException,因为你将DataInputStream对象传递给readAllInts方法,读取流,然后尝试在for循环中再次读取它。问题在于,当readAllInts返回时,跟踪您在流中的位置的指针已经接近流的末尾(或在流的末尾)。我怀疑它是接近结束,而不是它,因为readChar()方法立即抛出EOFException,当它只读取它希望能够读取的两个字节之一时它会这样做击中EOF。
要解决这个问题,可以在将reader传递给readAllInts方法之前调用data.mark(),然后在该方法返回后调用data.reset();这会将指针重新指向流的开头。 (这假设data.markSupported()为true。)
你也遇到了我们上面谈到的问题,你的计数器一次读取四个字节,你的字符阅读器一次读两个字节。你建议的将readAllInts的返回值加倍的方法会有所帮助(你也可以使用readChar()而不是readInt()。)
您仍然需要考虑如何处理奇数字节长的二进制文件的情况。您可以通过多种方式处理该问题。我今晚也打得写代码样本,但如果你明天仍然被卡住,请添加评论,我会看到我可以做些什么来帮助。