zoukankan      html  css  js  c++  java
  • java io read中申请读的长度与实际长度不同|RocketMQ源码

    今天,在读RockeMQ源码时,读到

    MIXALL中的file2string方法,然后测试一个文件,返回null, 特别奇怪,查看了下源码

    public static final String file2String(final File file) {
        if (file.exists()) {
            char[] data = new char[(int) file.length()];
            boolean result = false;
    
            FileReader fileReader = null;
            try {
                fileReader = new FileReader(file);
                int datalen = data.length;
                int len = fileReader.read(data, 0, datalen);
                
                result = (len == data.length);
            }
            catch (IOException e) {
                // e.printStackTrace();
            }
            finally {
                if (fileReader != null) {
                    try {
                        fileReader.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            if (result) {
                String value = new String(data);
                return value;
            }
        }
        return null;
    }

    原来是

    int datalen = data.length;
    int len = fileReader.read(data, 0, datalen);

    result = (len == datalen);

    因为len与datalen是不相等的原因。

    也就是file.length与read获取长度不同,

    两者有什么区别呢?

    查看源码:

     public long length() {
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkRead(path);
            }
            if (isInvalid()) {
                return 0L;
            }
            return fs.getLength(this);
        }
    @Override
    public native long getLength(File f);

    可以看到是调用了WinNTFileSystem的本地的方法

    而filereader.read源码则是

     sun.nio.cs.StreamDecoder extends java.io.Reader里的代码,同样不可见。。。

    两者什么时候相等呢?

    原来的文件是这样的:

    package bhz.test;
    
    import java.util.Date;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.transaction.TransactionConfiguration;
    import org.springframework.transaction.annotation.Transactional;
    
    import bhz.entity.Pay;
    import bhz.service.PayService;
    /** 
     * <br>类 名: BaseTest 
     * <br>描 述: 描述类完成的主要功能 
     * <br>作 者: bhz
     * <br>创 建: 2013年5月8日 
     * <br>版 本:v1.0.0 
     * <br>
     * <br>历 史: (版本) 作者 时间 注释
     */
    @ContextConfiguration(locations = {"classpath:applicationContext.xml" })
    @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
    @RunWith(SpringJUnit4ClassRunner.class)
    @Transactional(rollbackFor = Exception.class)
    public class BaseTest {
        
        
        @Autowired
        private PayService payService;
        
        @Test
        public void testSave() throws Exception {
            Pay pay = new Pay();
            pay.setUserid("z3");
            pay.setUsername("张三");
            pay.setAmount(5000d);
            pay.setDetail("0");
            pay.setUpdateBy("z3");
            pay.setUpdateTime(new Date());
            this.payService.insert(pay);
        }
        @Test
        public void testUpdate() throws Exception {
            System.out.println(this.payService);
            Pay pay = this.payService.selectByPrimaryKey("z3");
            pay.setAmount(pay.getAmount() - 1000d);
            pay.setUpdateTime(new Date());
            this.payService.updateByPrimaryKey(pay);
        }
    
    }

    我把file简单化,就写一行试试是可以的。

    实践证明

    加了以下是不可以的

    /** 
     * <br>类 名: BaseTest 
     * <br>描 述: 描述类完成的主要功能 
     * <br>作 者: bhz
     * <br>创 建: 2013年5月8日 
     * <br>版 本:v1.0.0 
     * <br>
     * <br>历 史: (版本) 作者 时间 注释
     */
    "张三"

    关键问题,居然是中文。。。。

    一个中文相差两个大小。。

    所以lentgh读的是字节,filereader读的是字符,在汉字上是两倍的问题,如果想让两个相等,则需要类型同样。比如用inputstream.reader

     其实这个类的目的,就是文件内不能有中文,如果读读取出来,result写true则ok

    相关参考

    java io --- Reader类
    https://blog.csdn.net/zhao123h/article/details/52831524

    RocketMQ使用Filter问题!
  • 相关阅读:
    LwIP应用开发笔记之六:LwIP无操作系统TCP客户端
    LwIP应用开发笔记之五:LwIP无操作系统TCP服务器
    LwIP应用开发笔记之四:LwIP无操作系统TFTP服务器
    幸运与不幸
    LwIP应用开发笔记之三:LwIP无操作系统UDP客户端
    LwIP应用开发笔记之二:LwIP无操作系统UDP服务器
    【文学】暖泉古镇
    Docker创建JIRA 7.2.4中文破解版
    cAdvisor0.24.1+InfluxDB0.13+Grafana4.0.2搭建Docker1.12.3 Swarm集群性能监控平台
    Centos7的安装、Docker1.12.3的安装,以及Docker Swarm集群的简单实例
  • 原文地址:https://www.cnblogs.com/stevenlii/p/8867041.html
Copyright © 2011-2022 走看看