如何在 Java 中将文件读取为无符号字节?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5144080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I read a file as unsigned bytes in Java?
提问by tyr
How can I read a file to bytes in Java?
如何在 Java 中将文件读取为字节?
It is important to note that all the bytes need to be positive, i.e. the negative range cannot be used.
需要注意的是,所有字节都必须为正数,即不能使用负数范围。
Can this be done in Java, and if yes, how?
这可以在 Java 中完成,如果是,如何完成?
I need to be able to multiply the contents of a file by a constant. I was assuming that I can read the bytes into a BigInteger and then multiply, however since some of the bytes are negative I am ending up with 12 13 15 -12 etc and get stuck.
我需要能够将文件的内容乘以一个常数。我假设我可以将字节读入 BigInteger 然后乘以,但是由于某些字节是负数,我最终得到 12 13 15 -12 等并卡住了。
回答by Jon Skeet
Well, Java doesn't have the concept of unsigned bytes... the byte
type is always signed, with values from -128 to 127 inclusive. However, this will interoperate just fine with other systems which have worked with unsigned values for example, C# code writing a byte of "255" will produce a file where the same value is read as "-1" in Java. Just be careful, and you'll be okay.
好吧,Java 没有无符号字节的概念……该byte
类型始终是有符号的,值从 -128 到 127(含)。但是,这将与使用无符号值的其他系统很好地互操作,例如,写入“255”字节的 C# 代码将生成一个文件,其中相同的值在 Java 中被读取为“-1”。小心点,你会没事的。
EDIT: You can convert the signed byte to an int
with the unsignedvalue very easily using a bitmask. For example:
编辑:您可以将符号字节转换为int
与无符号的价值很容易使用位掩码。例如:
byte b = -1; // Imagine this was read from the file
int i = b & 0xff;
System.out.println(i); // 255
Do all your arithmetic using int
, and then cast back to byte
when you need to write it out again.
使用 完成所有算术运算int
,然后byte
在需要再次写出时转换回。
You generally read binary data from from files using FileInputStream
or possibly FileChannel
.
您通常使用FileInputStream
或 可能从文件中读取二进制数据FileChannel
。
It's hard to know what else you're looking for at the moment... if you can give more details in your question, we may be able to help you more.
目前很难知道您还在寻找什么……如果您能在问题中提供更多详细信息,我们或许可以为您提供更多帮助。
回答by phuclv
With the unsigned API in Java 8you have Byte.toUnsignedInt
. That'll be a lot cleaner than manually casting and masking out.
使用Java 8 中的未签名 API,您可以拥有Byte.toUnsignedInt
. 这将比手动铸造和屏蔽要干净得多。
To convert the int
back to byte
after messing with it of course you just need a cast (byte)value
要在弄乱它之后转换int
回byte
,当然你只需要一个演员(byte)value
回答by Erik A. Brandstadmoen
If using a larger integer type internally is not a problem, just go with the easy solution, and add 128 to all integers before multiplying them. Instead of -128 to 127, you get 0 to 255. Addition is not difficult ;)
如果在内部使用更大的整数类型不是问题,那么只需使用简单的解决方案,并在乘以所有整数之前将其加 128。不是 -128 到 127,而是 0 到 255。加法并不难;)
Also, remember that the arithmetic and bitwise operators in Java only returns integers, so:
另外,请记住,Java 中的算术运算符和按位运算符只返回整数,因此:
byte a = 0;
byte b = 1;
byte c = a | b;
would give a compile time error since a | b returns an integer. You would have to to
会给出编译时错误,因为 | b 返回一个整数。你必须
byte c = (byte) a | b;
So I would suggest just adding 128 to all your numbers before you multiply them.
所以我建议在你乘以 128 之前把它们加到所有的数字上。
回答by Pa?lo Ebermann
You wrote in a comment (please put such informations in the question - there is an edit link for this):
您在评论中写道(请将此类信息放在问题中 - 有一个编辑链接):
I need to be able to multiply the contents of a file by a constant. I was assuming that I can read the bytes into a BigInteger and then multiply, however since some of the bytes are negative I am ending up with 12 13 15 -12 etc and gets stuck.
我需要能够将文件的内容乘以一个常数。我假设我可以将字节读入 BigInteger 然后乘以,但是由于某些字节是负数,我最终得到 12 13 15 -12 等并且卡住了。
If you want to use the whole file as a BigInteger, read it in a byte[], and give this array (as a whole) to the BigInteger-constructor.
如果要将整个文件用作 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);
}
}
Then you can multiply your BigInteger and save the result in a new file (using the toByteArray()
method).
然后你可以乘以你的 BigInteger 并将结果保存在一个新文件中(使用toByteArray()
方法)。
Of course, this very depends on the format of your file - my method assumes the file contains the result of the toByteArray()
method, not some other format. If you have some other format, please add information about this to your question.
当然,这在很大程度上取决于文件的格式 - 我的方法假定文件包含toByteArray()
方法的结果,而不是其他格式。如果您有其他格式,请将有关此的信息添加到您的问题中。
"I need to be able to multiply the contents of a file by a constant."seems quite a dubious goal - what do you really want to do?
“我需要能够将文件的内容乘以一个常数。” 似乎是一个很可疑的目标——你真正想做什么?
回答by Matthias Ronge
Some testing revealed that this returns the unsigned byte values in [0…255] range one by one from the file:
一些测试表明,这会从文件中一一返回 [0…255] 范围内的无符号字节值:
Reader bytestream = new BufferedReader(new InputStreamReader(
new FileInputStream(inputFileName), "ISO-8859-1"));
int unsignedByte;
while((unsignedByte = bytestream.read()) != -1){
// do work
}
It seems to be work for all bytes in the range, including those that no characters are defined for in ISO 8859-1.
它似乎适用于范围内的所有字节,包括那些在 ISO 8859-1 中没有定义字符的字节。