- 将数据以二进制方式写到文件中遇到一个坑
int 类型的值java本来占4个字节,写到文件中本以为是 00000000 00000000 00000000 00000000,可写进去发现只有一个字节00000000.
@Test
public void writeInt() throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("int.dat");
//1: 0b00000000 00000000 00000000 00000001
//结果 0b 00000001 0x01
fileOutputStream.write(1);
//65535: 0b00000000 00000000 11111111 11111111
//结果 0b 11111111 0xff
fileOutputStream.write(65535);
//2147483647: 0b01111111 11111111 11111111 11111111
//结果 0b 11111111 0xff
fileOutputStream.write(2147483647);
fileOutputStream.flush();
}
//看源码可知,参数虽然是一个int但是注释写的很明白,只写一个字节
/**
* Writes the specified byte to this file output stream. Implements
* the <code>write</code> method of <code>OutputStream</code>.
*
* @param b the byte to be written.
* @exception IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
write(b, append);
}
//那具体写的int的哪个字节呢
@Test
public void writeInt() throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("int.dat");
//65534: 0b 00000000 00000000 11111111 11111110
//结果 0b 11111110 0xfe
fileOutputStream.write(65534);
//65532: 0b 00000000 00000000 11111111 11111100
//结果 0b 11111100 0xfc
fileOutputStream.write(65532);
//65528: 0b 00000000 00000000 11111111 11111000
//结果 0b 11111000 0xf8
fileOutputStream.write(65528);
//65520: 0b 00000000 00000000 11111111 11110000
//结果 0b 11110000 0xf0
fileOutputStream.write(65520);
//65504: 0b 00000000 00000000 11111111 11100000
//结果 0b 11100000 0xe0
fileOutputStream.write(65504);
//65472: 0b 00000000 00000000 11111111 11000000
//结果 0b 11000000 0xc0
fileOutputStream.write(65472);
//65408: 0b 00000000 00000000 11111111 10000000
//结果 0b 10000000 0x80
fileOutputStream.write(65408);
//65280: 0b 00000000 00000000 11111111 00000000
//结果 0b 00000000 0x00
fileOutputStream.write(65280);
//65024: 0b 00000000 00000000 11111110 00000000
//结果 0b 00000000 0x00
fileOutputStream.write(65024);
//2147483392: 0b 01111111 11111111 11111111 00000000
//结果 0b 00000000 0x00
fileOutputStream.write(2147483392);
fileOutputStream.flush();
}
2 还有一个值得注意的是, toBinaryString()及toHexString() 高位的0不输出
//1
System.out.println(Integer.toBinaryString(1));
//1111 1111
System.out.println(Integer.toBinaryString(255));
// 1111 1111 1111 1111
System.out.println(Integer.toBinaryString(65535));
// 111 1111 1111 1111 1111 1111 1111 1111
System.out.println(Integer.toBinaryString(2147483647));
System.out.println(Integer.toHexString(1)); // 1
System.out.println(Integer.toHexString(255)); // ff
System.out.println(Integer.toHexString(65535)); // ffff
System.out.println(Integer.toHexString(2147483647)); // 7fff ffff
3 那如何将int的4个字节写入到文件中
- 未理解原理时
//获得int值原始内存byte[]
private byte[] getBytes(int hexInt, int byteNum) {
String s = Integer.toHexString(hexInt);
String stringByByteCount = getStringByByteCount(s, byteNum);
byte[] bytes = getBytes(stringByByteCount);
return bytes;
}
//获取对应字节长度的16进制字符串,不够前补0
private String getStringByByteCount(String hexString, int bytesCount) {
StringBuilder builder = new StringBuilder();
int zeroAddCount = bytesCount * 2 - hexString.length();
for (int i = 0; i < zeroAddCount; i++) {
builder.append("0");
}
return builder.append(hexString).toString();
}
//将16进制的字符串遍历返回相应byte[]
private byte[] getBytes(String hexContent) {
byte[] bytes = new byte[hexContent.length() / 2];
for (int i = 0; i < hexContent.length(); i += 2) {
String substring = hexContent.substring(i, i + 2);
int i1 = Integer.parseInt(substring, 16);
bytes[i / 2] = (byte) i1;
}
return bytes;
}
- 理解了原理
int a = 1;
byte[] bytes = new byte[4];
//每次右移8位,只取最后一个字节,放入对应索引下
for (int i = 0; i < bytes.length; i++) {
bytes[bytes.length - i - 1] = (byte) (a >> i * 8);
}
- 查看资料,找到更简便的方式
byte[] bytes = ByteBuffer.allocate(4).putInt(2).array();
ByteBuffer使用(allocate, wrap, order, put, get, rewind, flip, compact, array)
https://blog.csdn.net/mrliuzhao/article/details/89453082
字节序(endian) 大端字节序(big endian) 小端字节序(little endian)
https://www.cnblogs.com/gremount/p/8830707.html
网友评论