Android 上传大文件

最近工作需要实现使用 Android 手机上传图片的功能, 参考了网络上的很多资料, 不过网络上的代码都仅仅适合上传较小的文件, 当上传较大文件时(我在自己的测试机器上发现是 2M 左右), 就会因为内存不足发生异常。异常一般发生在两个地方, 1. 将需要上传的文件读取到内存缓存时, 2. 调用 HttpUrlConnection 的 OutputStream 发送数据时。 为了解决这两个问题, 我使用了将上传数据写入临时文件, 然后调用 HttpPost 类来发送数据的办法, 代码如下

private String post(String command, Map<String, String> params, String format, String name, String type, Bitmap content) throws Exception 
    { 
        String BOUNDARY                = "-------1A2B3C4D5E6F"; 
        String MULTIPART_FORM_DATA    = "multipart/form-data"; 
         
        OutputStream outStream = null; 
        File         tmpFile   = iHompyFile.createRandomFile(); 
        if (tmpFile == null) 
        { 
            outStream  = new ByteArrayOutputStream(); 
        } 
        else 
        { 
            outStream = new FileOutputStream(tmpFile); 
        } 
 
        /** 
         * 填写数据 
         */ 
        try 
        { 
            if (params != null) 
            { 
                for(Map.Entry<String, String> entry : params.entrySet()) 
                { 
                    outStream.write(("--" + BOUNDARY + "/r/n").getBytes()); 
                    outStream.write(("Content-Disposition: form-data; name=/"" + entry.getKey() + "/"/r/n/r/n").getBytes()); 
                    outStream.write(entry.getValue().getBytes()); 
                    outStream.write(("/r/n").getBytes()); 
                } 
            } 
            outStream.write(("--" + BOUNDARY + "/r/n").getBytes()); 
            outStream.write(("Content-Disposition: form-data; name=/"" + format + "/"; filename=/"" + name + "/"/r/n").getBytes()); 
            outStream.write(("Content-Type: " + type + "/r/n/r/n").getBytes()); 
            content.compress(Bitmap.CompressFormat.PNG, 100, outStream); 
            outStream.write(("/r/n--" + BOUNDARY + "--/r/n").getBytes()); 
        } 
        catch(Exception e) 
        { 
            throw new Exception("向数据流写入数据失败, 可能是内存空间不足!" + e.getMessage()); 
        } 
         
        HttpPost httpRequest = new HttpPost(myServer + command); 
        if (tmpFile != null) 
        { 
            outStream.flush(); 
            outStream.close(); 
             
            FileEntity entity = new FileEntity(tmpFile, MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY); 
            entity.setContentEncoding("UTF-8"); 
            httpRequest.setEntity(entity); 
        } 
        else 
        { 
            ByteArrayEntity entity = new ByteArrayEntity(((ByteArrayOutputStream)outStream).toByteArray()); 
            entity.setContentType(MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY); 
            entity.setContentEncoding("UTF-8"); 
            httpRequest.setEntity(entity); 
        } 
        
        HttpResponse httpResponse = myClient.execute(httpRequest); 
        int          httpCode     = httpResponse.getStatusLine().getStatusCode(); 
        if (tmpFile != null) 
        { 
            tmpFile.delete(); 
        } 
        if (httpCode != 200) 
        { 
            throw new Exception("Error response: " + httpResponse.getStatusLine().toString()); 
        } 
        return EntityUtils.toString(httpResponse.getEntity()); 
    }

测试时能成功发送 5M 左右的图片, 基本满足拍摄后上传照片的要求。

上一篇:django基础 -- 4. 模板语言 过滤器 模板继承 FBV 和CBV 装饰器 组件


下一篇:BZOJ1050 HAOI2006旅行(最小生成树+LCT)