我尝试将一个zip文件下载到android,然后解压缩zip文件。我调试我的代码,有一个有趣的问题:下载的zip文件比原始文件大一点。并且下载的zip文件不能被winrar解压缩。据说下载的文件以错误结束。 (我网站上的zip文件没问题。我尝试用IE下载。它运行正常。) 以下是我的代码:
public void download(final String url, final String savePath, final String saveName) {
new Thread(new Runnable() {
public void run() {
try {
sendMessage(FILE_DOWNLOAD_CONNECT);
URL sourceUrl = new URL(url);
URLConnection conn = sourceUrl.openConnection();
conn.connect();
InputStream inputStream = conn.getInputStream();
int fileSize = conn.getContentLength();
File savefilepath = new File(savePath);
if (!savefilepath.exists()) {
savefilepath.mkdirs();
}
File savefile = new File(savePath+saveName);
if (savefile.exists()) {
savefile.delete();
}
savefile.createNewFile();
FileOutputStream outputStream = new FileOutputStream(
savePath+saveName, true);
byte[] buffer = new byte[1024];
int readCount = 0;
int readNum = 0;
int prevPercent = 0;
while (readCount < fileSize && readNum != -1) {
readNum = inputStream.read(buffer);
if (readNum > -1) {
outputStream.write(buffer);
readCount = readCount + readNum;
int percent = (int) (readCount * 100 / fileSize);
if (percent > prevPercent) {
sendMessage(FILE_DOWNLOAD_UPDATE, percent,
readCount);
prevPercent = percent;
}
}
}
outputStream.flush();
outputStream.close();
inputStream.close();
//Thread.sleep(50);
sendMessage(FILE_DOWNLOAD_COMPLETE, savePath);
} catch (Exception e) {
sendMessage(FILE_DOWNLOAD_ERROR, e);
}
}
}).start();
}
有人知道这个问题吗?
答案 0 :(得分:5)
当您读入缓冲区时,您正在将整个缓冲区写入输出流:
outputStream.write(buffer);
您应该只编写已填充的缓冲区部分:
outputStream.write(buffer, 0, readNum);
特别是对于网络下载,无法保证对inputStream.read(buffer)
的调用将填充缓冲区(即使文件中有超过1024个字节)。
答案 1 :(得分:2)
public class Download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
public String app_name ;
public String urlpath ;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app_name="test.rar";
urlpath = "https://www.abc.com/download/"+ app_name;
if (android.os.Environment.getExternalStorageState().equals
(android.os.Environment.MEDIA_MOUNTED))
{
startDownload();
}
else
{
Toast.makeText(getApplicationContext(), "SD Card not found,Insert SD card and try again", Toast.LENGTH_SHORT).show();
}
}
private void startDownload() {
new DownloadFileAsync().execute(urlpath);
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading Updates..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
@Override
protected String doInBackground(String... aurl) {
try {
URL url = new URL(urlpath.toString()); // Your given URL.
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect(); // Connection Complete here.!
int lenghtOfFile = c.getContentLength();
Log.d("Downloading Updates", "Lenght of file: " + lenghtOfFile);
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH); // PATH = /mnt/sdcard/download/
if (!file.exists()) {
file.mkdirs();
}
File outputFile = new File(file, app_name);
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream(); /
byte[] buffer = new byte[1024];
int len1 = 0;
long total = 0;
while ((len1 = is.read(buffer)) != -1) {
total += len1;
publishProgress(""+(int)((total*100)/lenghtOfFile));
fos.write(buffer, 0, len1); // Write In FileOutputStream.
}
fos.flush();
fos.close();
is.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("Downloading Updates",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
finish();
}
}
}