FileOutputStream、BufferedOutputStream、FileWriter三種檔案寫入的對比
阿新 • • 發佈:2019-01-23
因為需要把線上的apk檔案下載到本地,一上來就使用了FileWriter的方式進行檔案寫入,結果發現下載到本地的apk會提示安裝包損壞,經過排查,原來FileWriter是使用的字元寫入的方式,而可執行的apk實際是二進位制檔案,這樣在位元組讀取,字元寫入的時候檔案顯然也發生了變化,明顯的差異就是檔案大小變成了兩倍……
官方解釋是:
這裡總結一下,我常用的檔案寫入的方法有三種:FileOutputStream、BufferedOutputStream、FileWriter,前兩種都是位元組寫入。那麼這三種方法的差異有什麼呢?這篇文章大致比較了這三種方法的效能差異:http://xiaofan-0204.iteye.com/blog/1317668 。<span style="white-space:pre"> </span>FileOutputStream is meant for writing streams of raw bytes such as image data. For writing streams of characters, consider using FileWriter.
FileWriter程式碼示例:
public String GetMergedMap(String buildurl, String typeregx, String contentregx, String localfile) { ArrayList<String> urls = new ArrayList<String>(); urls = getLinkURL(buildurl, typeregx); File local = new File(localfile); if (local.exists()) { local.delete(); } try { local.createNewFile(); FileWriter fw = new FileWriter(localfile); OkHttpClient httpclient = new OkHttpClient(); Request request; for (int i = 0; i < urls.size(); i++) { String url = urls.get(i); logger.info("{}", "下載:" + url); request = new Request.Builder().url(url).build(); Response response = httpclient.newCall(request).execute(); if (response.isSuccessful()) { InputStream is = response.body().byteStream(); BufferedReader br = new BufferedReader( new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { if (line.matches(contentregx)) { fw.append(line + "\r\n"); fw.flush(); } } } else { logger.error("{}", "請求失敗 " + response.headers().get("code")); System.exit(0); } } fw.close(); } catch (IOException e) { // TODO Auto-generated catch block logger.error("{}", "map檔案下載失敗"); } finally { logger.error("{}", "全部下載完畢"); return localfile; } }
FileOutputStream程式碼示例:
<span style="white-space:pre"> </span>public String downloadApkOnline(String url, String localfile) { File local = new File(localfile); if (local.exists()) { local.delete(); } try { local.createNewFile(); int chByte = 0; OkHttpClient httpclient = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); Response response = httpclient.newCall(request).execute(); InputStream is = response.body().byteStream(); chByte = is.read(); FileOutputStream fos = new FileOutputStream(localfile); while(chByte != -1) { fos.write(chByte); chByte = is.read(); } fos.flush(); fos.close(); is.close(); } catch (IOException e) { // TODO Auto-generated catch block logger.error("{}", "下載失敗"); } finally { return localfile; } }
BufferedOutputStream程式碼示例:
<span style="white-space:pre"> </span>public String downloadApkByBuffer(String url, String localfile)
{
File local = new File(localfile);
if (local.exists()) {
local.delete();
}
try {
local.createNewFile();
int chByte = 0;
OkHttpClient httpclient = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = httpclient.newCall(request).execute();
InputStream is = response.body().byteStream();
chByte = is.read();
FileOutputStream fos = new FileOutputStream(localfile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
while(chByte != -1)
{
bos.write(chByte);
chByte = is.read();
}
bos.flush();
bos.close();
fos.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
logger.error("{}", "下載失敗");
} finally {
return localfile;
}
}