在Android中上传大文件而不会出现内存不足错误 [英] Upload large file in Android without outofmemory error

查看:39
本文介绍了在Android中上传大文件而不会出现内存不足错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的上传代码如下:

String end = "
";
String twoHyphens = "--";
String boundary = "*****";
try {
    URL url = new URL(ActionUrl);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setDoInput(true);
    con.setDoOutput(true);
    con.setUseCaches(false);
    con.setRequestMethod("POST");
    con.setRequestProperty("Connection", "Keep-Alive");
    con.setRequestProperty("Accept", "text/*");
    con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    DataOutputStream ds = new DataOutputStream(con.getOutputStream());
    ds.writeBytes(twoHyphens + boundary + end);
    ds.writeBytes("Content-Disposition: form-data;" + "name="folder"" + end + end);
    ds.write(SavePath.getBytes("UTF-8"));
    ds.writeBytes(end);
    ds.writeBytes(twoHyphens + boundary + end);
    ds.writeBytes("Content-Disposition: form-data;" + "name="Filedata"; filename="");
    ds.write(FileName.getBytes("UTF-8"));
    ds.writeBytes(""" + end);
    ds.writeBytes(end);
    FileInputStream fStream = new FileInputStream(uploadFilepath+""+FileName);
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];
    int length = -1;
    int pro = 0;
    while((length = fStream.read(buffer)) != -1) {
        ds.write(buffer, 0, length);
    }       
    ds.writeBytes(end);
    ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
    fStream.close();
    ds.flush();
    InputStream is = con.getInputStream();
    int ch;
    StringBuffer b = new StringBuffer();
    while((ch = is.read()) != -1) {
        b.append((char)ch);
    }
    ds.close();
}
catch(Exception e) {
    e.printStackTrace();
}

虽然小于 16 mb,但它上传成功.但当它超过 16 mb 时,OutOfMemory"错误显示.如何避免内存不足错误?

While smaller than 16 mb, it upload success. But while it more than 16 mb, the "OutOfMemory" error show. How to avoid the outofmemory error?

推荐答案

你试过了吗

con.setChunkedStreamingMode(1024);

这将帮助您将数据分块为特定大小,这样您就无需将整个文件保存在内存中.

This will help you to chunk your data into specific size, so that you need not keep your entire file in the memory.

更新:

尝试使用以下方法.我使用这种方法上传一个 80 mb 的文件,没有异常.

Try using the below method. I use this method to upload a 80 mb file without Exception.

public String sendFileToServer(String filename, String targetUrl) {
    String response = "error";
    Log.e("Image filename", filename);
    Log.e("url", targetUrl);
    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    // DataInputStream inputStream = null;

    String pathToOurFile = filename;
    String urlServer = targetUrl;
    String lineEnd = "
";
    String twoHyphens = "--";
    String boundary = "*****";
    DateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH:mm:ss");

    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024;
    try {
        FileInputStream fileInputStream = new FileInputStream(new File(
                pathToOurFile));

        URL url = new URL(urlServer);
        connection = (HttpURLConnection) url.openConnection();

        // Allow Inputs & Outputs
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setChunkedStreamingMode(1024);
        // Enable POST method
        connection.setRequestMethod("POST");

        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type",
                "multipart/form-data;boundary=" + boundary);

        outputStream = new DataOutputStream(connection.getOutputStream());
        outputStream.writeBytes(twoHyphens + boundary + lineEnd);

        String connstr = null;
        connstr = "Content-Disposition: form-data; name="uploadedfile";filename=""
                + pathToOurFile + """ + lineEnd;
        Log.i("Connstr", connstr);

        outputStream.writeBytes(connstr);
        outputStream.writeBytes(lineEnd);

        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        buffer = new byte[bufferSize];

        // Read file
        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        Log.e("Image length", bytesAvailable + "");
        try {
            while (bytesRead > 0) {
                try {
                    outputStream.write(buffer, 0, bufferSize);
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                    response = "outofmemoryerror";
                    return response;
                }
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }
        } catch (Exception e) {
            e.printStackTrace();
            response = "error";
            return response;
        }
        outputStream.writeBytes(lineEnd);
        outputStream.writeBytes(twoHyphens + boundary + twoHyphens
                + lineEnd);

        // Responses from the server (code and message)
        int serverResponseCode = connection.getResponseCode();
        String serverResponseMessage = connection.getResponseMessage();
        Log.i("Server Response Code ", "" + serverResponseCode);
        Log.i("Server Response Message", serverResponseMessage);

        if (serverResponseCode == 200) {
            response = "true";
        }

        String CDate = null;
        Date serverTime = new Date(connection.getDate());
        try {
            CDate = df.format(serverTime);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("Date Exception", e.getMessage() + " Parse Exception");
        }
        Log.i("Server Response Time", CDate + "");

        filename = CDate
                + filename.substring(filename.lastIndexOf("."),
                        filename.length());
        Log.i("File Name in Server : ", filename);

        fileInputStream.close();
        outputStream.flush();
        outputStream.close();
        outputStream = null;
    } catch (Exception ex) {
        // Exception handling
        response = "error";
        Log.e("Send file Exception", ex.getMessage() + "");
        ex.printStackTrace();
    }
    return response;
}

这篇关于在Android中上传大文件而不会出现内存不足错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆