java int与byte[]转换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_23318779/article/details/82950136

今天写一个小程序,需要将int数组写入文件,然后再读出来。为了节省空间,打算采用直接把每个int的字节码写入文件,读的时候也是按照int的字节码直接进行读取,省略了逗号、换行符等格式编码。

第一次尝试:

FileOutputStream fOut = new FileOutputStream(f);
for(int i = 0 ; i < intArray.length ; i++){
	fOut.write(intArray[i]);
}

省略了异常处理,FileOutputStream能直接输出int,感觉还挺方便。但是读取的时候,问题就来了,以下为读取的代码:

byte[] byteA = new byte[Integer.SIZE / 8];
while(fInput.read(byteA) > 0){
	System.out.println(this.byteArrayToInt(byteA));
}
		

每次读取4个byte,然后将按照位运算转化为int,流程很简单,但是运行起来有问题。

假设我在文件中输入了128,512两个数字,文件中只要存着以下内容即可保证程序正常运行:

00000000 00000000 00000000 10000000 00000000 00000000 00000010 00000000

但是,文件中实际存着的却是10000000 00000000原来使用FileOutputStream直接输出int,只会截取int中最低的一个八位组,丢弃其他高位八位组。

因此,还是需要将int转化为byte[]后再输出到文件。

第二次尝试:

增加了intToByteArray的转换,第一次我是这么写的,基础不扎实

……
    for(int i = 0 ; i < intArray.length ; i++){
		fOut.write(this.intToByteArray(intArray[i]));
	}
……
private byte[] intToByteArray(int value){
	byte[] byteArray = new byte[4];
	byteArray[0] = (byte) (value & 0xFF);
	byteArray[1] = (byte) (value & 0xFF00);
	byteArray[2] = (byte) (value & 0xFF0000);
	byteArray[3] = (byte) (value & 0xFF000000);
	return byteArray;
}

运行了一遍后,妥妥的有错,改成如下所示:

private byte[] intToByteArray(int value){
	byte[] byteArray = new byte[4];
	byteArray[0] = (byte) (value & 0xFF);
	byteArray[1] = (byte) (value >> 8  & 0xFF);
	byteArray[2] = (byte) (value >> 16 & 0xFF);
	byteArray[3] = (byte) (value >> 24 & 0xFF);
	return byteArray;
}

即可向文件中写入int的byte[4]编码。

然后是读取的代码,只要保证读写大小端法一致就行,没有硬性要求

……
    byte[] byteA = new byte[Integer.SIZE / 8];
    while(fInput.read(byteA) > 0){
    	System.out.println(this.byteArrayToInt(byteA));
    }
……
private int byteArrayToInt(byte[] byteArray){
    if(byteArray.length != 4){
		return 0;
	}
	int value = byteArray[0];
	value |= byteArray[1] << 8;
	value |= byteArray[2] << 16;
	value |= byteArray[3] << 24;
	return value;
}

每次读取4个byte,将其转为int,读取是没问题,但是转换有问题。

假设将1007写入文件,即00000000 00000000 00000011 11101111,byte[]读出来后,会显示为[-17,3,0,0],执行过我的byteArrayToInt方法后,最终结果为-17。经过测试发现,只要最后一个八位组的值为负,最终结果就是最后一个八位组的显示值,如果为正,则可正常转换。

问题就在于int value = byteArray[0],这个byte与int的类型转换上,-17在byte中为11101111,转为int后,会补位成为11111111 11111111 11111111 11101111,之后的几次或运算就不会有任何效果。同理,char转int、int转long等低转高时,都需要注意补位的问题。

将代码做如下修改,即可解决问题:

private int byteArrayToInt(byte[] byteArray){
    if(byteArray.length != 4){
		return 0;
	}
	int value = byteArray[0] & 0xFF;
	value |= byteArray[1] << 8;
	value |= byteArray[2] << 16;
	value |= byteArray[3] << 24;
	return value;
}

现将最低的八位组用0xFF“重置“一遍,之后即可正常运行。

至此,将int数组写入文件并读取的代码基本完成。

总结

1、FileOutputStream直接输出int,会截取最低的八位组输出,抛弃其余高位

2、byte转int、char转int、int转long等低转高时,以及使用>>进行位运算时,需要注意补位会使用最高位进行补位,而不是使用0进行补位。

猜你喜欢

转载自blog.csdn.net/qq_23318779/article/details/82950136