1. 程式人生 > >FileOutputStream、BufferedOutputStream、FileWriter三種檔案寫入的對比

FileOutputStream、BufferedOutputStream、FileWriter三種檔案寫入的對比

因為需要把線上的apk檔案下載到本地,一上來就使用了FileWriter的方式進行檔案寫入,結果發現下載到本地的apk會提示安裝包損壞,經過排查,原來FileWriter是使用的字元寫入的方式,而可執行的apk實際是二進位制檔案,這樣在位元組讀取,字元寫入的時候檔案顯然也發生了變化,明顯的差異就是檔案大小變成了兩倍……

官方解釋是:

<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.
這裡總結一下,我常用的檔案寫入的方法有三種:FileOutputStream、BufferedOutputStream、FileWriter,前兩種都是位元組寫入。那麼這三種方法的差異有什麼呢?這篇文章大致比較了這三種方法的效能差異:http://xiaofan-0204.iteye.com/blog/1317668 。

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;
		}
	}