如何在Android中以编程方式下载文件以提高速度

时间:2018-06-19 12:22:46

标签: android downloading

Hi已使用inputstream和cipheroutputstream(用于加密)以编程方式实现了文件的下载。下载进行得很慢。而如果我尝试通过下载管理器进行下载,则速度非常快。我该怎么做才能改善代码并提高文件的下载速度。下面是我的代码。

 private void saveFileUsingEncryption(String aMineType, long length) throws Exception {

    int bufferSize = 1024*4;

    //byte[] buffer = new byte[1024];
    byte[] buffer = new byte[bufferSize];
    int bytesRead = 0;
    long totalRead = 0;

    FileOutputStream outStream = null;

    File f = new File(Constants.DWLPATH);
    if (!f.exists()) {
        f.mkdirs();
    }

    try {

        Cipher aes = Cipher.getInstance("ARC4");
        aes.init(Cipher.ENCRYPT_MODE,  new SecretKeySpec("mykey".getBytes(), "ARC4"));

        if(contDisp==null || contDisp.length()==0) {
            // downloadFileName = downloadFileName.replaceAll("[^a-zA-Z0-9_]+", "");
            downloadFileName = downloadFileName + "." + getFileExtension(aMineType);

        }

        outStream = new FileOutputStream(Constants.DWLPATH +  downloadFileName,true);
        CipherOutputStream out = new CipherOutputStream(outStream, aes);

        while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) >= 0) {

            out.write(buffer, 0, bytesRead);

            try{
                // Adjust this value. It shouldn't be too small.
                Thread.sleep(50);
            }catch (InterruptedException e){
              TraceUtils.logException(e);
            }
            totalRead += bytesRead;
            sb=sb.append("\n Total bytes Read:"+totalRead);
            Log.e("--",sb.toString());
           /* if (this.length > 0) {
                Long[] progress = new Long[5];
                progress[0] = (long) ((double) totalRead / (double) this.length * 100.0);


                publishProgress(progress);
            }*/

            if (this.isCancelled()) {
                if (conn != null)
                    conn.disconnect();
                conn = null;
                break;
            }

        }
        Log.e("Download completed","success");
        out.flush();
        //Utils.putDownloadLogs(requestUrl,mimeType,length, downloadFileName,"Download is Successful",sb.toString(), context);
        outStream.close();


        buffer = null;


    } catch (Exception e) {
        TraceUtils.logException( e);

        file_newsize = storedFileSizeInDB + totalRead;
        if (totalFileSize == 0)
            totalFileSize = length;

        callback.onRequestInterrupted(file_newsize,totalFileSize);

        StringWriter errors = new StringWriter();
        e.printStackTrace(new PrintWriter(errors));
        // Utils.putDownloadLogs(requestUrl,mimeType,length,downloadFileName,"failure---" + errors.toString(),sb.toString(), context);


        throw e;

    } finally {
        if (outStream != null)
            outStream.close();
        outStream = null;
    }
}

2 个答案:

答案 0 :(得分:0)

您可以使用默认的下载管理器来下载文件,因为它非常易于实现,并提供了更好的功能,例如响应Internet连接,提供了在状态栏中添加通知的可访问性,通过对下载管理器对象运行查询,您可以找到总字节数和剩余字节数,以便您可以计算进度,并在完成下载后通过点击通知来执行所需的操作。

还有很多库可用于实现此目的

PRDOWNLOADER
FetchDownloader

此库为您提供暂停,下载,恢复下载,跟踪进度和取消下载的功能

您还可以根据需要自定义它。

答案 1 :(得分:0)

这里是DownloadAndEncryptFileTask.class进行加密下载

public class DownloadAndEncryptFileTask extends AsyncTask<Void, Void, Void> {

private String mUrl;
private File mFile;
private Cipher mCipher;

InputStream inputStream;
FileOutputStream fileOutputStream;
CipherOutputStream cipherOutputStream;

public DownloadAndEncryptFileTask(String url, File file, Cipher cipher) {
    if (url == null || url.isEmpty()) {
        throw new IllegalArgumentException("You need to supply a url to a clear MP4 file to download and encrypt, or modify the code to use a local encrypted mp4");
    }
    mUrl = url;
    mFile = file;
    mCipher = cipher;
}

private void downloadAndEncrypt() throws Exception {

    URL url = new URL(mUrl);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    if (mFile.length() > 0) {
        connection.setRequestProperty("Range", "bytes=" + mFile.length() + "-");
    }
    connection.connect();

    Log.e("length", mFile.length() + "");


    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
        throw new IOException("server error: " + connection.getResponseCode() + ", " + connection.getResponseMessage());
    }


    inputStream = connection.getInputStream();
    if (mFile.length() > 0) {
        //connection.connect();
        fileOutputStream = new FileOutputStream(mFile, true);

    } else {
        fileOutputStream = new FileOutputStream(mFile);
    }

    CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, mCipher);

    byte buffer[] = new byte[1024 * 1024];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        Log.d(getClass().getCanonicalName(), "reading from http...");

        cipherOutputStream.write(buffer, 0, bytesRead);
    }

    inputStream.close();
    cipherOutputStream.close();
    connection.disconnect();
}

@Override
protected Void doInBackground(Void... params) {
    try {
        downloadAndEncrypt();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    Log.d(getClass().getCanonicalName(), "done");
}
}

呼叫此类

new DownloadAndEncryptFileTask(
    myFeedsModel.getVideo().getVideo360(),
    new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), myFeedsModel.getFile_name()),
    OBJECT OF YOUR CIPHER