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問題!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章