【问题标题】:How do you transfer a inputstream from a ftp server directly to S3 multipart Upload?如何将输入流从 ftp 服务器直接传输到 S3 分段上传?
【发布时间】:2015-01-16 11:44:07
【问题描述】:

我正在尝试将一个大文件(大约 2gb 到 3gb)从客户端的 FTP 服务器上传到我的 Amazon S3 存储桶位置。
现在我不允许将整个文件存储在我的远程应用程序服务器中,所以不允许中间停车。此外,除了 SFTP,我对客户端 ftp 服务器没有其他访问权限。
你有什么特别的建议吗??

同样,现在我正在使用 JSCH 库将 Ftp 服务器中的文件作为 Inputstream 读取,然后将相同的 Inputstream 传递给 UploadPartRequest。另请注意,我可以使用 JSCH 库从客户端接收文件大小,以便制作多部分文件。 这是我一直在尝试的示例代码。

BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsKey, awsSecretKey);
    AmazonS3 s3Client = new AmazonS3Client(awsCreds);
    List<PartETag> partETags = new ArrayList<PartETag>();
    InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(existingBucketName, keyName);
    InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest);
    try {
        long partSize = 50 * 1024 * 1024;
        jsch= new JSch();
        session = jsch.getSession(ftpUserName, ftpLocation, 22);
        session.setPassword(password);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setTimeout(0);
        session.connect();
        System.out.println("session connected ......" + session.isConnected());
        channel = session.openChannel("sftp");
        channel.connect();
        System.out.println("channel connected...." + channel.isConnected());
        c = (ChannelSftp) channel;
        SftpATTRS attrs = c.lstat(filePath);
        long contentLength = attrs.getSize();
        InputStream is = c.get(filePath);
        System.out.println("size of the file in remote location is : " + contentLength/(1024*1024) +" MB" );
        long filePosition = 0;
        for (int i = 1; filePosition < contentLength; i++) {
            partSize = Math.min(partSize, (contentLength - filePosition));
            UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(existingBucketName)
                    .withKey(keyName).withUploadId(initResponse.getUploadId())
                    .withPartNumber(i).withFileOffset(filePosition).withInputStream(is).withPartSize(partSize);
            boolean anotherPass;
            do {
                anotherPass = false;
                try {
                    partETags.add(s3Client.uploadPart(uploadRequest).getPartETag());
                } catch (Exception e) {
                    anotherPass = true;
                }
            } while (anotherPass);

        filePosition += partSize;
            System.out.println("new file pos is : " + filePosition/(1024*1024) +" MB");
        }
        CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(existingBucketName, keyName, initResponse.getUploadId(), partETags);
        s3Client.completeMultipartUpload(compRequest);
    } catch (Exception ex){
        System.out.println("Exception occurred : " + ex.getMessage());
        s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
                existingBucketName, keyName, initResponse.getUploadId()));
        ex.printStackTrace();
    }finally {
        System.out.println("closing all connections !!!!");
        if(session != null){
            session.disconnect();
        }if(channel != null){
            channel.disconnect();
        }if(c != null){
            c.disconnect();
        }
    }


现在使用这种方法,当上传到达中间某处时,整个上传过程就会停止。应用程序正在运行,但没有上传或下载网络,上传停止在 50% 左右。
大家有什么建议吗???

【问题讨论】:

    标签: java file-upload amazon-s3 sftp jsch


    【解决方案1】:

    要调试它,我会尝试查看问题出在哪里。

    首先,您可以解耦此代码以从 FTP 连接中获取一个小尺寸的字节数组缓冲区,例如 10k,并在每次迭代时丢弃缓冲区(不要将其发送到 S3),看看是否是否仍然挂起。

    如果这可行,您可以一次将此字节块发送到 S3,看看会发生什么。

    【讨论】:

    • 那么问题就出现在大于 700Mb 的大小上。小文件很容易上传到 s3。不过感谢您的建议:)
    • 整个 2Gb 或 3Gb 一次 10k
    猜你喜欢
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2017-04-26
    相关资源
    最近更新 更多