如何在Java中将文件读取为字节?
需要注意的是,所有字节都需要是正数,即不能使用负范围。
在Java中是否可以实现此操作,如果可以,如何实现?
我需要能够将文件内容乘以一个常数。我假设可以将字节读入BigInteger然后进行乘法运算,但由于某些字节为负数,我最终得到12 13 15 -12等结果并且无法继续操作。
嗯,Java 没有无符号字节的概念......byte
类型始终是带符号的,其值范围从 -128 到 127(含)。然而,这将与其他已使用无符号值的系统很好地进行交互,例如,C# 代码写入一个字节的“255”将生成一个文件,在 Java 中读取相同的值为“-1”。只要小心谨慎,就不会出问题。
编辑:您可以使用掩码非常轻松地将带符号字节转换为具有无符号值的 int
。例如:
byte b = -1; // Imagine this was read from the file
int i = b & 0xff;
System.out.println(i); // 255
在所有算术运算中使用int
,然后在需要重新写出时将其转换回byte
。
通常使用FileInputStream
或可能是FileChannel
从文件中读取二进制数据。
目前很难知道您还在寻找什么其他内容...如果您在问题中提供更多细节,我们可能能够更好地帮助您。
BigInteger
?如果是后者,我不明白为什么你要将字节转换为它们的无符号表示形式。 - someguyBigInteger
。抱歉。 - someguyByte.toUnsignedInt
函数。这比手动转换和掩码处理要更加简洁。(byte)value
即可。如果在内部使用更大的整数类型不是问题,那么就选择简单的解决方案,在将它们相乘之前将所有整数加上128。这样,你可以得到0到255而不是-128到127。加法并不困难 ;)
此外,请记住Java中的算术和位运算符仅返回整数,因此:
byte a = 0;
byte b = 1;
byte c = a | b;
会产生编译时错误,因为 | 运算符返回的是整型。你需要这样做:
byte c = (byte) a | b;
所以我建议在将数字相乘之前,将它们全部加上128。
您在评论中写道(请将此类信息放入问题中 - 有一个编辑链接可供使用):
我需要能够将文件的内容乘以一个常数。 我假设我可以将字节读入BigInteger,然后进行乘法运算, 但由于某些字节是负数,我最终得到12 13 15 -12等结果并卡住了。
如果要将整个文件用作BigInteger,请将其读入byte []中,并将此数组(作为整体)提供给BigInteger构造函数。
/**
* reads a file and converts the content to a BigInteger.
* @param f the file name. The content is interpreted as
* big-endian base-256 number.
* @param signed if true, interpret the file's content as two's complement
* representation of a signed number.
* if false, interpret the file's content as a unsigned
* (nonnegative) number.
*/
public static BigInteger fileToBigInteger(File f, boolean signed)
throws IOException
{
byte[] array = new byte[file.length()];
InputStream in = new FileInputStream(file);
int i = 0; int r;
while((r = in.read(array, i, array.length - i) > 0) {
i = i + r;
}
in.close();
if(signed) {
return new BigInteger(array);
}
else {
return new BigInteger(1, array);
}
}
然后,您可以将BigInteger乘以并将结果保存在新文件中(使用toByteArray()
方法)。
当然,这非常取决于您的文件格式 - 我的方法假设文件包含toByteArray()
方法的结果,而不是其他格式。如果您有其他格式,请在问题中添加相关信息。
“我需要能够将文件内容乘以一个常数。”似乎是一个相当可疑的目标 - 您真正想要做什么?
Reader bytestream = new BufferedReader(new InputStreamReader(
new FileInputStream(inputFileName), "ISO-8859-1"));
int unsignedByte;
while((unsignedByte = bytestream.read()) != -1){
// do work
}
看起来它适用于范围内的所有字节,包括 ISO 8859-1 中未定义字符的字节。
DataInputStream
提供了readUnsignedByte()
方法。 - Adrian Grygutis