在黑莓边缘应用程序中上传文件(超过2 MB)时连接关闭

时间:2014-05-29 23:49:40

标签: java blackberry blackberry-simulator

我正试图将文件从黑莓应用程序上传到亚马逊s3。

这是我的代码

  private synchronized void uploadFileToAmazon(CreateFileIdBean createFileIdBean)       throws UnsupportedEncodingException, IOException,ConnectionNotFoundException, ConnectionClosedException, BackupCancelledException, InterruptedException, BackupInterruptedException {

        String BOUNDARY = "----------V2ymHFg03ehbqgZCaKO6jy";

        String Policy = "{\"expiration\": \"2020-12-01T12:00:00.000Z\","
                + "\"conditions\": ["
                + "{\"bucket\": \"" + BeanFactory.getUserCreateBackupidBean().getBucketName() + "\"},"
                + "{\"x-amz-security-token\": \"" + BeanFactory.getUserCreateBackupidBean().getAmazonToken() + "\"},"
                + "{\"success_action_status\": \"201\"},"
                + "[\"starts-with\", \"$Content-Type\", \"\"],"
                + "[\"starts-with\", \"$key\", \"" + BeanFactory.getUserCreateBackupidBean().getBackupPath() + "\"]"
                + "]"
                + "}";
        String encodePolicy = Base64.encode(Policy.getBytes());
        String signature = uploadSignature(Policy, BeanFactory.getUserCreateBackupidBean().getAmazonSecret());
        Hashtable params = new Hashtable();
        params.put("key", BeanFactory.getUserCreateBackupidBean().getBackupPath() + "/" + BeanFactory.getUserCreateFileIdBean().getFileId());
        params.put("AWSAccessKeyId", BeanFactory.getUserCreateBackupidBean().getAmazonKey());
        params.put("Content-Type", createFileIdBean.getFileTypeContent());
        params.put("x-amz-security-token", BeanFactory.getUserCreateBackupidBean().getAmazonToken());
        params.put("policy", encodePolicy);
        params.put("success_action_status", "201");
        params.put("Signature", signature);

        send(BOUNDARY, "http://" + BeanFactory.getUserCreateBackupidBean().getBucketName() + ".s3.amazonaws.com/", params, "file", BeanFactory.getUserCreateFileIdBean().getFileId(), createFileIdBean.getFileTypeContent(), createFileIdBean.getFileByte(), createFileIdBean);

    }

    private synchronized String getBoundaryMessage(String boundary, Hashtable params, String fileField, String fileName, String fileType, byte[] fileBytes, CreateFileIdBean createFileIdBean) {
        StringBuffer res = new StringBuffer("--").append(boundary).append("\r\n");

        Enumeration keys = params.keys();

        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            String value = (String) params.get(key);

            res.append("Content-Disposition: form-data; name=\"").append(key).append("\"\r\n")
                    .append("\r\n").append(value).append("\r\n")
                    .append("--").append(boundary).append("\r\n");
        }

        return res.toString();
    }

    private synchronized void send(String boundarry, String url, Hashtable params, String fileField, String fileName, String fileType, byte[] fileBytes, CreateFileIdBean createFileIdBean) throws IOException,ConnectionClosedException,ConnectionNotFoundException, BackupCancelledException, InterruptedException, BackupInterruptedException {


            StringBuffer buffer = new StringBuffer();

            HttpConnection hc = null;
            InputStream is = null;
            InputStream inputFileDataStream = null;
            DataOutputStream dout = null;

            String boundary = boundarry;
            StringBuffer res = new StringBuffer();

            int ch;

            String boundaryMessage = getBoundaryMessage(boundary, params, fileField, fileName, fileType, fileBytes, createFileIdBean);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bos.write(boundaryMessage.getBytes());

            res.append("Content-Disposition: form-data; name=\"").append(fileField).append("\"; filename=\"").append(fileName).append("\"\r\n")
                    .append("Content-Type: ").append(fileType).append("\r\n\r\n");

            bos.write(res.toString().getBytes());

            String end = "\r\n"+"--"+boundary+"\r\n"+"Content-Disposition: form-data; name=\""+"submit"+"\"\r\n"+"\r\n"+"Upload to Amazon S3"+"\r\n"+"--"+boundary+"--\r\n";

            try {

                    hc = (HttpConnection) Connector.open(url+Resources.getConnectionString(), Connector.READ_WRITE,true);
                    hc.setRequestMethod(HttpConnection.POST);
                    hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundarry);
                    hc.setRequestProperty("User-Agent", Resources.getUserAgentString());
                    //hc.setRequestProperty("User-Agent", "Profile/MIDP-1.0 Confirguration/CLDC-1.0");
                    hc.setRequestProperty("Content-Language", "en-US");
                    hc.setRequestProperty("Connection", "Keep-Alive");
                    hc.setRequestProperty("Keep-Alive", "300");
                    hc.setRequestProperty("Expect", "100-continue");

                    hc.setRequestProperty("Content-Length", (bos.toByteArray().length+createFileIdBean.getFileSize()+end.getBytes().length)+"");
                    hc.setRequestProperty("Content-length", (bos.toByteArray().length+createFileIdBean.getFileSize()+end.getBytes().length)+"");

                    dout = new DataOutputStream(hc.openDataOutputStream());

                    dout.write(bos.toByteArray());


            inputFileDataStream = readInputStream(createFileIdBean.getFilePath());

                        while ((ch = inputFileDataStream.read()) != -1) {

            dout.write(ch);

            }   

                    dout.write(end.getBytes());

                    dout.flush();
                    //dout.close();


                    is = hc.openDataInputStream();

                    BeanFactory.getUserUploadFileBean().setResponseCode(hc.getResponseCode() + "");
                    BeanFactory.getUserUploadFileBean().setResponseMessage(hc.getResponseMessage());

                    while ((ch = is.read()) != -1) {

                        buffer.append((char) ch);
                    }

                    System.out.println("buffer"+buffer);

            } 
            catch (IOException e) {
                throw new BackupInterruptedException(Constants.ERROR_IN_UPLOAD);

            } finally {
                try {
                    if (is != null) {
                        is.close();
                    }
                    if (hc != null) {
                        hc.close();
                    }
                    if(inputFileDataStream !=null)
                    {
                        inputFileDataStream.close();
                    }
                    if(dout !=null)
                    {
                        dout.close();
                    }


                } catch (IOException e2) {
                    System.out.println("aa"+e2.getMessage());
                    throw e2;
                }
            }
    }

    private synchronized String uploadSignature(String policy, String secretKey) throws UnsupportedEncodingException {

        String encodePolciy = Base64.encode(policy.getBytes());
        HMac m = new HMac(new SHA1Digest());
        m.init(new KeyParameter(secretKey.getBytes("UTF-8")));
        byte[] bytes = encodePolciy.getBytes("UTF-8");
        m.update(bytes, 0, bytes.length);
        byte[] mac = new byte[m.getMacSize()];
        m.doFinal(mac, 0);
        String signature = Base64.encode(mac);
        return signature;
    }

   private synchronized InputStream readInputStream(String path) throws IOException {

        FileConnection fc = null;
        InputStream is = null;

        fc = (FileConnection) Connector.open(path.toString(), Connector.READ);
        if (!fc.exists()) {
            Settings.ERROR_MESSAGE = "File doesn't exist!";
            //throw new BackupInterruptedException(Settings.ERROR_MESSAGE);
        } else {
             is = fc.openInputStream();
        }
        if(fc !=null)
        {
            fc.close();
        }
        return is;
    }

当我在上传数据后尝试获取响应代码时(在 BeanFactory.getUserUploadFileBean()。setResponseCode(hc.getResponseCode()+“”); )中,它始终获得连接关闭异常。对于小于2MB的文件,其工作正常。请帮帮我......

2 个答案:

答案 0 :(得分:2)

我对HttpConnection的体验是它总是在发送任何内容之前缓冲完整的有效负载。对于BlackBerry Curve 8520,16mb的数据最终导致设备无法使用。我通过使用原始SocketConnection并在我的应用程序中直接编写HTTP部分来解决这个问题,因此我可以确保在字节到达套接字之前没有任何过多的缓冲。

我后来意识到可能有用的一个领域是使用HTTP-Chunked模式和内置的HttpConnection对象。由于HTTP-Chunked基本上是一种流机制,它可以让你摆脱默认情况下的“缓冲所有”逻辑。

答案 1 :(得分:0)

如果您尝试传输大文件,则可能会遇到可怕的HTTP错误413.如果我的内存正确,则允许的最大文件大小介于1到30 MB之间,具体取决于传输类型(BIS,BES等)。 / p>

除此之外,应用程序还有可用的RAM配额。对于较旧的83XX型号,我们凭经验发现应用程序的最大内存大约为12MB。

但我们使用分块连接(使用HTTP Range标头)成功传输大文件,而对于缓冲区,我们使用小数组(<< 12 MB)或临时文件。

我将发布有关该主题的经典链接:

How to Download large files using the BlackBerry Mobile Data System
What is: HTTP 413 Request entity too large

您可以在BB论坛或其他网站上找到有关它们的信息。