[英]How can I read a file as unsigned bytes in Java?
如何在Java中讀取文件到字節?
重要的是要注意所有字節都需要是正的,即不能使用負范圍。
這可以用Java完成,如果可以,怎么做?
我需要能夠將文件的內容乘以常量。 我假設我可以將字節讀入BigInteger然后相乘,但是因為一些字節是負數,所以最終得到12 13 15 -12等並且卡住了。
好吧,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
從文件中讀取二進制數據。
現在很難知道你還在尋找什么......如果你能在你的問題中提供更多細節,我們可以幫助你。
使用Java 8中的未簽名API,您可以使用Byte.toUnsignedInt
。 這將比手動投射和屏蔽更清潔。
在搞亂它之后將int
轉換回byte
當然你只需要一個cast (byte)value
如果在內部使用更大的整數類型不是問題,只需使用簡單的解決方案,並在乘以它們之前將128添加到所有整數。 而不是-128到127,你得到0到255.添加並不困難;)
另外,請記住Java中的算術運算符和按位運算符只返回整數,因此:
byte a = 0;
byte b = 1;
byte c = a | b;
會因為|而給出編譯時錯誤 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()
方法的結果,而不是其他格式。 如果您有其他格式,請在您的問題中添加相關信息。
“我需要能夠將文件的內容乘以常量。” 似乎是一個非常可疑的目標 - 你真的想做什么?
一些測試顯示,這會從文件中逐個返回[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中未定義字符的字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.