如何在Java中将文件读取为无符号字节?

时间:2011-02-28 15:41:28

标签: java file byte

如何在Java中读取文件到字节?

重要的是要注意所有字节都必须是正数,即不能使用负范围。

这可以用Java完成,如果可以,怎么做?

我需要能够将文件的内容乘以常量。我假设我可以将字节读入BigInteger然后相乘,但是由于一些字节是负数,所以最终会得到12 13 15 -12等并且卡住了。

5 个答案:

答案 0 :(得分:16)

嗯,Java没有无符号字节的概念...... byte类型始终是有符号的,其值从-128到127(含)。但是,这将与其他使用无符号值的系统进行互操作,例如,写入“255”字节的C#代码将生成一个文件,其中相同的值在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从文件中读取二进制数据。

目前很难知道您还在寻找什么...如果您能在问题中提供更多详细信息,我们可以为您提供更多帮助。

答案 1 :(得分:2)

使用unsigned API in Java 8 Byte.toUnsignedInt。这比手动投射和掩盖更清洁。

要在弄乱它之后将int转换回byte,当然你需要一个演员(byte)value

答案 2 :(得分:1)

如果在内部使用较大的整数类型不是问题,只需使用简单的解决方案,并在乘以它们之前将128添加到所有整数。而不是-128到127,你得到0到25​​5.添加并不困难;)

另外,请记住Java中的算术运算符和按位运算符只返回整数,所以:

byte a = 0;
byte b = 1;

byte c = a | b;

会因为|而产生编译时错误b返回一个整数。你必须

byte c = (byte) a | b;

因此,我建议您在将它们相乘之前将所有数字加128.

答案 3 :(得分:1)

您在评论中写道(请在问题中添加此类信息 - 有一个编辑链接):

  

我需要能够将文件的内容乘以常量。   我假设我可以将字节读入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()方法的结果,而不是其他格式。如果您有其他格式,请在您的问题中添加相关信息。

“我需要能够将文件的内容乘以常量。”似乎是一个非常可疑的目标 - 你真的想做什么?

答案 4 :(得分:0)

一些测试显示,这会从文件中逐个返回[0 ... 255]范围内的无符号字节值:

Reader bytestream = new BufferedReader(new InputStreamReader(
        new FileInputStream(inputFileName), "ISO-8859-1"));
int unsignedByte;
while((unsignedByte = bytestream.read()) != -1){
    // do work
}

它似乎适用于范围内的所有字节,包括那些在ISO 8859-1中未定义字符的字节。