平時寫IO相關(guān)代碼機會挺少的,但卻都知道使用BufferedXXXX來讀寫效率高,沒想到里面還有這么多陷阱,這兩天突然被其中一個陷阱折騰一下:讀一個文件,然后寫到另外一個文件,前后兩個文件居然不一樣?
解決這個問題之后,總結(jié)了幾個注意點。
public?void?copyFile1()?{ File?srcFile?=?new?File("E://atest//atest.txt"); File?dstFile?=?new?File("E://btest//btest.txt"); BufferedReader?in?=?null; BufferedWriter?out?=?null; try?{ in?=?new?BufferedReader(new?FileReader(srcFile)); out?=?new?BufferedWriter(new?FileWriter(dstFile)); String?line?=?null; while((line?=?in.readLine())?!=?null)?{ out.write(line+"/r/n"); } }catch?(Exception?e)?{ //?TODO:?handle?exception e.printStackTrace(); }finally?{ if(in?!=?null)?{ try?{ in.close(); }catch?(Exception?e)?{ //?TODO:?handle?exception e.printStackTrace(); } } if(out?!=?null)?{ try?{ out.close(); }catch?(Exception?e)?{ //?TODO:?handle?exception e.printStackTrace(); } } }
上面代碼使用BufferedReader一行一行地讀取一個文件,然后使用BufferedWriter把讀取到的數(shù)據(jù)寫到另外一個文件中。如果文件是ASCCII形式的,則內(nèi)容還是能夠正確讀取的。但如果文件是二進制的,則讀寫后的文件與讀寫前是有很大區(qū)別的。當然,把上面的readLine()換成read(char[])仍然不能正確讀寫二進制文件的。讀寫二進制文件請接著看下面注意點。
注意點二:read(byte[]b,int offset,int length)中的offset不是指全文件的全文,而是字節(jié)數(shù)組b的偏移量
現(xiàn)在已經(jīng)知道使用Reader/Writer不能正確讀取二進制文件,這是因為Reader/Writer是字符流,那就改用字節(jié)流ufferedInputStream/BufferedOutputStream,網(wǎng)上搜索到的例子大概是這樣的:
public?void?copyFile()?{ File?srcFile?=?new?File("E://atest//atest.gif"); File?dstFile?=?new?File("E://atest//btest.gif"); BufferedInputStream?in?=?null; BufferedOutputStream?out?=?null; try?{ in?=?new?BufferedInputStream(new?FileInputStream(srcFile)); out?=?new?BufferedOutputStream(new?FileOutputStream(dstFile)); byte[]?b?=?new?byte[1024]; while(in.read(b)?!=?-1)?{ out.write(b); } }catch?(Exception?e)?{ //?TODO:?handle?exception e.printStackTrace(); }finally?{ if(in?!=?null)?{ try?{ in.close(); }catch?(Exception?e)?{ //?TODO:?handle?exception e.printStackTrace(); } } if(out?!=?null)?{ try?{ out.close(); }catch?(Exception?e)?{ //?TODO:?handle?exception e.printStackTrace(); } } } }
每次讀1024字節(jié),然后寫1024字節(jié)。這看似挺正確的,但實際寫出來的文件與原文件是不同的。這樣就懷疑可能是讀寫沒有接上,因而把代碼改成下面的形式:
byte[]?b?=?new?byte[1024]; int?offset?=?0; int?length?=?-1; while((length?=?in.read(b,?offset,?1024))?!=?-1)?{ out.write(b,?offset,?length); offset?+=?length; }
這是誤以為:先讀一段,寫一段,然后改變偏移量,然后使用新的偏移量再讀一段、寫一段,直到文件讀寫完畢。但這是錯誤的,因為使用BufferedXXX后,里面已經(jīng)實現(xiàn)了這個過程。而read(byte[] b, int offset, int length)中的offset實際指的是把讀到的數(shù)據(jù)存入到數(shù)組b時,從數(shù)組的哪個位置(即offset)開始放置數(shù)據(jù);同理,write(byte[] b, int offset, int length)就是把b中的數(shù)據(jù),從哪個位置(offset)開始寫到文件中。
以上就是長沙達內(nèi)教育java培訓(xùn)機構(gòu)的小編針對“Java的IO流讀寫文件需要注意的幾點”的內(nèi)容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務(wù)。