因为需要把在线的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;
}
}