关于Redis 二进制内容的 可视化尝试

二进制内容的 能否可视化?  网上的资料比较少啊!

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

有时候通过 可视化工具,比如redis DesktopManager 查看 redis 的key 的值的时候,发现是 二进制内容, 如下:

出现二进制的内容, 丝毫不奇怪,因为我set的时候value就是key。怪的是, 为什么有的 英文字母 能够展示出来, 其他就都是\x ,可能是 这个工具本身做了一些处理吧。  但其实不然, 如果命令行登录进去一看,发现也是一样的 结果:

127.0.0.1:6379[2]> get DISCUSS:TOPIC:3d28016e7cb34119aab718da2d4d1fe5::count
"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x00"

可以看到其中 java.lang.Integer java.lang.Number 都是 类名。

另外注意到 如果 notepad++打开一个二进制文件, 比如class文件,那么也会看到这样的 乱码和 英文夹杂的情况。 为什么会这样 ?

写个程序测试下:

package com.lkk;

import com.alibaba.fastjson.JSONObject;import com.baomidou.mybatisplus.plugins.Page;import com.lkk.ppm.discuss.domain.entity.ELComment;import io.lettuce.core.RedisClient;import io.lettuce.core.RedisURI;import org.apache.commons.codec.binary.Hex;import org.junit.Assert;import org.junit.Test;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.connection.RedisStringCommands;import org.springframework.data.redis.connection.lettuce.LettuceConnection;import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializationContext;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.util.ByteUtils;

import javax.xml.bind.DatatypeConverter;import java.io.ByteArrayInputStream;import java.io.FileInputStream;import java.net.URL;import java.nio.ByteBuffer;

/** * @author Administrator * @date 2019/9/5 0005 12:40 * @Description */public class TestRedisSerializer {

    private static final int CURRENT = 111;    private static final int SIZE = 222;

    static RedisSerializer serial;    static RedisSerializationContext.SerializationPair serializationPair;    static RedisStringCommands redisStringCommands;

    static {        RedisURI redisURI = RedisURI.create("192.168.11.200", 6380);        redisURI.setPassword("Redis!123");        long jedis = 100000L;        RedisConnection connection = new LettuceConnection(jedis, RedisClient.create(redisURI));        connection.select(2);

        redisStringCommands = connection.stringCommands();        // 切换 序列化组件        serial = new JdkSerializationRedisSerializer();// 默认就是 JdkSerializationRedisSerializer

//          StringRedisSerializer 只能够序列化字符串, 不能序列化 对象。 好像没啥用!//       serial = new StringRedisSerializer();

        // GenericFastJsonRedisSerializer 可以将对象序列化为 json格式字符串//        serial = new GenericFastJsonRedisSerializer();

        serializationPair = RedisSerializationContext.SerializationPair.fromSerializer(serial);    }

    @Test    public void testHex() throws Exception {//        ByteUtils.getBytes(this.cacheConfig.getValueSerializationPair().write(value)//         ByteUtils.getBytes(this.cacheConfig.getValueSerializationPair().write(value)//        org.apache.commons.compress.utils.ByteUtils.

        String foo = "hello";        byte[] bytes = foo.getBytes("unicode");        bytes = foo.getBytes();//        bytes = foo.getBytes("gb2312");

        /**         * 虽然foo 是纯英文字母,但 下面的方法都 无法将bytes 还原到上面的hello 了。。 TODO         */        System.out.println( Hex.encodeHexString( bytes ) );// 结果是 纯16进制的内容 68656c6c6f,不带 \ x 无法查看        String s = DatatypeConverter.printHexBinary(bytes);;// 结果是 纯16进制的内容 68656c6c6f, 无法查看        System.out.println("s = " + s);//        byte[] decoded = Hex.decodeHex("00A0BF");//        System.out.println("decoded = " + new String(decoded));

        /**         *  还原到上面的hello         */        dumpBytesToHex(bytes);

        // 尝试读取class文件        // 当前文件        String fileFullName = "E:\\dev\\erdp2\\erdp_discuss\\erdp_discuss_service\\target\\test-classes\\com\\lkk\\TestRedisSerializer.class";        FileInputStream fis = new FileInputStream(fileFullName);//        fis.getChannel()//        ByteArrayInputStream//        fis.read()        int available = fis.available();        byte[] classBytes = new byte[available];        int read = fis.read(classBytes);

        String s1 = dumpBytesToHex(classBytes);// 除了换行符,基本上 得到了 和 notepad++ 一样的效果。        Assert.assertTrue(s1.contains("TestRedisSerializer"));

        ClassLoader classLoader = TestRedisSerializer.class.getClassLoader();

    }

    @Test    public void testWrite() throws Exception {        String key = "RESOURCE:ITEM:FILE::9fd04b83e33844b1a21ffa1c05978fc1_content.js";//        key = "RESOURCE:ITEM:FILE::3fa4bbdff660490092ba9af971980838_template.html";//        key = "DISCUSS:TOPIC:3d28016e7cb34119aab718da2d4d1fe5::count";        key = "DISCUSS:TOPIC:xxx::count";        write(key);    }

    private void write(Object key) throws Exception {        /**         * CURRENT SIZE 测试read 要用到         */        Page<ELComment> page = new Page<>(CURRENT, SIZE);        String s2 = JSONObject.toJSONString(page);//        byte[] bytes = ByteUtils.getBytes(serializationPair.write(key));

        //如果是 JdkSerializationRedisSerializer : write 1 结果是  "\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"//        byte[] bytes = ByteUtils.getBytes(serializationPair.write(1));

        byte[] bytes = ByteUtils.getBytes(serializationPair.write(page));        Boolean set = redisStringCommands.set(key.toString().getBytes(), bytes);//        System.out.println("set = " + set);//        byte[] bytes = ByteUtils.getBytes(RedisSerializationContext.SerializationPair.fromSerializer(serial).write(new String("abc阿斯蒂芬")));//        System.out.println("bytes = " + bytes.length);        String s = dumpBytesToHex(bytes);        Assert.assertTrue(s.contains("com.baomidou.mybatisplus.plugins.Page"));    }

    @Test    public void testRead() throws Exception {        String key = "DISCUSS:TOPIC:xxx::count";        read(key);    }

    private void read(String key) {        byte[] bytes1 = redisStringCommands.get(key.getBytes());        System.out.println("TestRedis.aaa");        System.out.println("bytes1 === " + new String(bytes1));// 直接打印 二进制内容        System.out.println("TestRedis.bbb");        dumpBytesToHex(bytes1);// 打印 16 进制内容

        Page<ELComment> read = (Page<ELComment>) serializationPair.read(ByteBuffer.wrap(bytes1));        System.out.println("read = " + read);        int pages = read.getPages();        int size = read.getSize();        System.out.println("size = " + size);        Assert.assertEquals(read.getSize(), SIZE);        Assert.assertEquals(read.getCurrent(), CURRENT);    }

    /**     * 转换为16进制 再打印     * @param bytes     * @return     */    public static String dumpBytesToHex(byte[] bytes) {        String s = bytesToHex(bytes);        System.out.println("Hex String:\n" + s);        return s;    }

    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex66(byte[] bytes) {        StringBuffer sb = new StringBuffer();        char[] hexChars = new char[bytes.length * 2];        for (int j = 0; j < bytes.length; j++) {            byte aByte = bytes[j];            if (aByte > 33 && aByte < 128) {                sb.append((char) aByte);                continue;            }            int v = bytes[j] & 0xFF;            hexChars[j * 2] = HEX_ARRAY[v >>> 4];            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];

            String hex = Integer.toHexString(aByte & 0xFF);            sb.append("\\x");            sb.append(hex);            if (hex.length() < 2) {                if (aByte == 0) {//                    continue; // Fixme ,                } else {                }                sb.append(0); // Fixme ,            }        }//        return new String(hexChars);        return sb.toString();    }

    /**     * @param bytes     * @return     */    public static String bytesToHex(byte[] bytes) {        StringBuffer sb = new StringBuffer();        for (int i = 0; i < bytes.length; i++) {            byte aByte = bytes[i];

            /**             * 这一段是做 ascii码字符 转换             */            if (aByte > 33 && aByte < 128) {                sb.append((char) aByte);                continue;            }            String hex = Integer.toHexString(aByte & 0xFF);            sb.append("\\x");            sb.append(hex);            if (hex.length() < 2) {                if (aByte == 0) {//                    continue;                } else {                }                sb.append(0);            }        }        return sb.toString();    }

}

Binary Viewer 查看的 结果是:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

总结:

二进制的内容, 可以用hex 查看/编辑器 进行查看, 一般情况下 是无法直接转换为 字符串的!! 二进制的内容 如果 用hex 查看器查看,发现确实有字符串,那么可能就是 它本身就是 刚好被查看器支持直接展示了吧。

网上很多的二进制转 16进制的 所谓工具, 其实 其结果并不是Redis 客户端展示的结果,不是我想要的。。 因为它对 字符串的不能直接解析出来。。

16 进制不能阅读, 可以尝试转换为ascii。 二进制其实就是内存的内容,任何文件都可以转换为二进制。 软件把它展示出来, 它需要按照特定的 编码格式。文本内容是 天生可以用 文本编辑器 查看的。 其他的 , 比如 图片, 需要图片查看器, 依次类推。 class文件 呢?   其实也有专门的 查看器。。

注意到 其中 \ x 其实是一个 方便终端展示的一个 程序添加的 字符。 并不是 二进制内容自带的。

StringRedisTemplate默认使用的是StringRedisSerializer, 默认只能用来存储value类型为 string 的值。。

Redis 自带的序列化器是的JdkSerializationRedisSerializer,也就是我们 生成我们 class 文件的 二进制序列化器。 其生成的结果很臃肿, 效率是比较低的!

参考:

https://www.jianshu.com/p/23f2c4c92093

https://blog.csdn.net/Eric_Blog_CSDN/article/details/78904679

posted on 2019-09-16 21:44 CanntBelieve 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/FlyAway2013/p/11530244.html

关于Redis 二进制内容的 可视化尝试相关推荐

  1. resource.arsc二进制内容解析 之 Dynamic package reference

    目录 1.加载Theme出错 2.aapt中的特殊处理 3.RES_TABLE_LIBRARY_TYPE 4.dynamicRefTable位置 5.验证dynamicRefTable 6.总结 1. ...

  2. resource.arsc二进制内容解析 之 RES_TABLE_TYPE_TYPE (Config List)

    目录 1.resource.arsc结构 2.RES_TABLE_TYPE_TYPE 3.ResTable_type 4.ResTable_entry偏移数组 5.ResTable_entry(非ba ...

  3. 修改MP4文件二进制内容,实现安卓Camera2旋转录制视频画面功能

    Camera2比起Camera的自定义程度更高一点,比如可以同时输出多个视频流分别用于显示预览画面和录制视频.但是!不同于Camera可以直接使用setOrientation方法直接设置视频旋转角度, ...

  4. Redis配置文件redis.conf内容完整版

    为什么需要这个了? 因为在使用docker安装redis的时候,我们需要进行文件和目录的挂载,这就包括redis.conf配置文件,因此我们可以在linux主机下的redis.conf里面填上内容,当 ...

  5. java 删除二进制内容_二进制搜索树节点删除不删除替换Java

    我试图从二进制搜索树中删除节点.除了一个特定的情况,我可以成功删除树上的任何其他节点.如果目标节点有2个子节点,并且左子节点具有右子树,我可以找到正确的替换节点并将值切换到目标节点,但是永远不会删除替 ...

  6. Redis系列内容完整版

    文章目录 Redis系列之_Redis介绍安装配置 第一章 redis初识 1.1 Redis是什么 1.2 Redis特性(8个) 1.3 Redis单机安装 1.3.1下载安装 1.3.2三种启动 ...

  7. linux redis图形界面,linux安装redis和windows安装可视化工具

    Redis的安装 本文使用的是redis-4.x的版本,因为有些新技能,所以还是想试试 下载redis的安装包: wget http://download.redis.io/releases/redi ...

  8. redis 队列内容批量获取

    redis队列的批量获取一直以来让我很困惑,今天又遇到了同样的问题,经过几番波折,终于找到了一个方法.分享一下 只需要redis自带的两个方法(lrange, ltrim) lrange可以获取队列中 ...

  9. php redis 二进制,php-redis扩展

    php安装phpreids扩展 wget http://pecl.php.net/get/redis-2.2.7.tgz; tar -zxvf redis-2.2.7.tgz; cd redis-2. ...

最新文章

  1. 字符转char android,android – 如何在kotlin语言中将char转换为ascii值
  2. python深拷贝和浅拷贝的使用场景_深拷贝、浅拷贝的理解与使用场景
  3. 转:C#动态循环生成button怎么分别写他们的事
  4. 如何求欧拉函数~转载
  5. python3程序转python2_python2到python3代码转化:2to3
  6. @EnableConfigurationProperties 注解和@ConfigurationProperties注解实现配置绑定
  7. 前端学习(1782):前端调试之canvas简介
  8. LVS高可用方案汇总
  9. 微信多开txt_微信(电脑版)多开教程
  10. C语言 判断一个数是否为素数
  11. 实现企业员工外出登记(二)
  12. TypeError: unhashable type: ‘numpy.ndarray‘
  13. Collection与Map
  14. 怎样用UE4把一个Actor直接打包成Pak
  15. ArcGIS实验教程——实验四十三:ArcGIS栅格重分类(Reclass)案例详解
  16. 你的头发还好吗?大数据分析脱发城市哪里强
  17. Entity Framework Core系列教程-1
  18. 自体脂肪填充面部能保持多长时间,这是能说的吗
  19. 【IoT】 产品设计:硬件产品经理核心能力培养
  20. 大疆2022 “拓疆者” 校园招聘

热门文章

  1. 华为liteos内存管理源码以及架构分析
  2. 计算机操作员三级对职称有用吗,辛苦评定的职称,退休之后就没用了?其实还有三个作用你知道吗?...
  3. Wallpaper Changer
  4. ubuntu 双硬盘分区方案
  5. 投影幕布选购避坑指南!
  6. 借路人卡多刷4百 事情原因大曝光怎么还钱?
  7. 微信小程序中根据字母选择城市
  8. 网格员计算机应用基础知识,计算机应用基础(第3版)周南岳(win7office10)期末复习及答案.doc...
  9. springboot处理参数再转发请求_Springboot 2.0---WebFlux请求处理流程
  10. 自媒体批量下载短视频软件,批量下载短视频有诀窍