2

所以,我不得不参加一个工作面试的测试,我被要求编写一个执行简单 XOR 加密的迷你应用程序,并遇到了这个问题。我使用 FileInputReader 来拉入每个字节,使用密钥执行 XOR 操作,然后将结果推回 FileOutputStream。这就是让我思考的原因。

FileInputStream 返回一个 int,一个 32 位有符号类型。当只接收一个字节时,您可以将其转换为“字节”类型。如果 FileInputStream 达到 EOF,它也会返回 -1。但是,二进制补码中的 -1 == 0xff,那么如果读取的字节真的是 0xff,而不是 EOF 怎么办?

0xff 是一个在数学上永远不会返回的字节,除非在特殊情况下(例如 EOF)?还是根据您正在阅读的数据,您可能需要考虑这种情况?

4

4 回答 4

13

不,an 中的 -1int不是0xff,而是0xffffffff。Anint在 Java 中是 32 位。

在将值转换为 之前byte,请检查它是否为 -1。

read类方法的 API 文档FileInputStream解释了这一点:

从此输入流中读取数据的下一个字节。值字节作为 int 返回,范围为 0 到 255。如果由于到达流的末尾而没有可用的字节,则返回值 -1。此方法会一直阻塞,直到输入数据可用、检测到流结束或引发异常。

因此,如果0xff在输入中找到具有该值的字节,该read方法将返回int值为 255 ( 0xff) 的一个。只有在 EOF 上,它才会返回 -1(0xffffffff存储在 中时int)。

于 2011-09-15T14:58:54.213 回答
2

你可以:

int value = is.read();
if (value == -1)
   // the end!
else
{
   byte b = (byte) value;
   // use b
}

无论如何,我应该使用块读取(尝试读取字节数组),如果返回的字节数为零,那么我们就完成了:

int count;
byte[] buffer = new byte[8192];
while ((count = is.read(buffer)) > 0) {
   // use buffer from pos 0 to pos count-1
}
于 2011-09-15T14:59:27.730 回答
1

0xff 在基数 256 中仅为 -1,您在基数 2^32 中工作,因此不会造成混淆。即使你写了(signed char)-1(是的,我知道这不是有效的 Java,请耐心等待),它最终仍然写为 0xff。

您可以放心地假设任何负返回都是错误,并且正常的字节值是文件中逐字写入的内容。

于 2011-09-15T15:00:26.103 回答
0

Read 方法在 FileInputStream 类中没有实现,它必须有一个特定于操作系统的实现,它会告诉我们实际上是如何检查 EOF 处理的。

于 2011-09-15T15:04:25.913 回答