今天,在讀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