2011-02-28 148 views
5

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

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

这可以在Java中完成,如果是,如何?

我需要能够乘以一个常量的文件的内容。我假设我可以将字节读入一个BigInteger然后进行乘法运算,但是由于一些字节是负数,所以我以12 13 15 -12等结束,并且卡住了。

回答

15

那么,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从文件中读取二进制数据。

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

+0

我需要能够通过一个常数乘以一个文件的内容。我假设我可以将字节读入一个BigInteger然后相乘,但是由于一些字节是负数,我以12 13 15 -12等结束,并且卡住了。 – tyr 2011-02-28 15:48:27

+0

@tyr:编辑... – 2011-02-28 15:49:29

+0

谢谢我认为它可以这样工作,:) – tyr 2011-02-28 15:53:01

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,然后再乘以它们。

+1

假设他想从二进制补码转换为无符号的,那是行不通的。例如-1 + 128等于127 *不是* 255,因为它应该是。而且,转换回一个字节会改变字节范围以外的任何值。 – someguy 2011-02-28 16:41:21

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()方法的结果,而不是其他格式。如果您有其他格式,请在您的问题中添加相关信息。

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

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中没有定义字符。

相关问题