JAVA 将相应值所占内存写入到文件中

  1. 将数据以二进制方式写到文件中遇到一个坑
    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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容