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问题!
原文地址:https://www.cnblogs.com/stevenlii/p/8867041.html