S3上传器在尝试上传大文件时抛出异常

时间:2012-10-11 16:24:57

标签: ios macos amazon-s3 amazon-web-services nsexception

我试图使用Amazon sdk上传一个巨大的文件(8GB)用于MAC(虽然他们没有MAC的sdk,我已经修改了IOS sdk源代码,删除了UIKit引用并重新编译为MAC)。它实际上适用于文件,可能高达800MB~1GB。但每当我尝试上传8GB文件时,我都会遇到异常。例外情况说“互联网连接丢失”。很奇怪,我有良好的互联网连接(2Mbps上传速度: - /)。我正在使用multipart上传API并上传5MB的块。当我得到一个例外,我不会放弃,但我将重试相同的块至少5次,然后放弃。在这次重试之间,我睡了几秒钟。但最令人惊讶的是,一旦一个块上传面临例外,它将无法真正重试。我不明白。任何人都可以帮我解决????

提前致谢!

下面我也在添加代码!

        fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];

        S3InitiateMultipartUploadRequest* initReq = [[S3InitiateMultipartUploadRequest alloc] initWithKey:requestDetails.md5 inBucket:requestDetails.bucket];
        initReq.contentType = requestDetails.contentType;

        S3MultipartUpload* upload = [amazonS3Client_ initiateMultipartUpload:initReq].multipartUpload;
        S3CompleteMultipartUploadRequest* compReq = [[S3CompleteMultipartUploadRequest alloc] initWithMultipartUpload:upload];


        compReq.contentType = requestDetails.contentType;

        NSData* data = [fileHandle readDataOfLength:PART_SIZE];
        int part = 0;
        ...............................
        while([data length] > 0)
        {
                @try {
                    S3UploadPartRequest* upReq = [[S3UploadPartRequest alloc] initWithMultipartUpload:upload];
                    upReq.partNumber = part + 1;
                    upReq.contentLength = data.length;
                    upReq.data = data;
                    upReq.contentType = requestDetails.contentType;

                    response = [amazonS3Client_ uploadPart:upReq];
                    [compReq addPartWithPartNumber:(part + 1) withETag:response.etag];

                    offset += [data length];

                    [fileHandle seekToFileOffset:offset];
                    data = [fileHandle readDataOfLength:PART_SIZE];
                    part++;
                    ........................
                }
                @catch (AmazonClientException *exception) {
                    .............................

                    if([exception.message rangeOfString:@"expire"].location != NSNotFound)
                    {
                        // renew credentials code 
                        return [self multipartUpload:requestDetails withFilePath:filePath];
                    }

                }
            }
      [amazonS3Client_ completeMultipartUpload:compReq];

1 个答案:

答案 0 :(得分:2)

我是AWS SDK for iOS的维护者之一。虽然我们没有测试过那个大小的文件,但我无法想到SDK中会导致这种情况的任何内容。您可能想要尝试和/或包含在您的问题中的一些事情:

  1. 适用于iOS的AWS开发工具包的最新版本包括禁用SDK本身的例外情况的选项。这可能会显示异常来源是否在SDK或其他内容。

  2. 您说您正在重试异常,但是您是在重新使用请求还是创建新请求?包含您的代码可能有助于其他人提供建议。

  3. 当你进入这种状态时,你可以执行任何其他操作吗?您确定没有以某种方式重置网络连接吗?

  4. 跟进

    过去几天,我花了很多时间尝试使用最新版本的AWS SDK for iOS重现问题,并且没有成功。我能够使用分段上传成功将10GB文件上传到Amazon S3。

    我想总结一些调查结果并为后续步骤提供一些建议:

    1. 您应该真正更新SDK。自您说下载以来,已经有6个月的AWS SDK for iOS发布了许多更新,其中一些与连接处理相关,可能有助于解决此问题。

    2. 您对互联网连接的测试可能无法正确测试。你没有包含这个代码,所以目前还不清楚,但如果你所测试的只是本地设备有链接并且可以到达他们的网关,那么这不一定是你的网站没有问题的有效指标连接到Amazon S3。您获得超时的事实(稍后会详细介绍)表明您的计算机出现了连接到Amazon S3的问题。造成这种情况的原因有很多,包括网络硬件故障或ISP明确的流量整形。

    3. SDK在超时处理方面存在不一致之处。对于除S3之外的所有客户端,超时将应用于NSURLConnection对象以及处理实际请求。对于S3,它仅应用于处理请求,这意味着NSURLConnection timeoutInverval属性未被修改。 NSURLConnection timeoutInterval属性是建立连接的超时。一旦发送或接收数据,即使它只是涓涓细流,NSURLConnection也不会超时。这意味着,如果您收到超时异常,则您的计算机无法与Amazon S3建立连接以获取默认的timeoutInterval(60秒)。我们将酌情审核并修补SDK以解决此不一致问题。

    4. 正如我在原始答案中所述,最好确认您是否可以向Amazon S3发送另一个请求(如列表存储桶/对象)以及访问其他外部资源(如google.com)你进入这种失败状态。这至少可以让你去你的ISP,并询问更好的问题。

    5. 希望此信息有所帮助