1

Rackspace クラウド ファイルから mp3 ファイルをダウンロードしています。大きなファイルの場合、ダウンロードは正常に完了しましたが、ファイルがまだ完全にダウンロードされていないという問題が発生しています。たとえば、40 MBmp3 ファイル (01:00:00期間) は mp3 ファイル (期間) としてダウンロードされ4.5 MBます00:10:30。これは常に起こるわけではありません。

  1. 何が起こっているかについての指針はありますか?
  2. この問題はなぜ発生し、どうすればこの問題を解決できますか?
  3. ファイルが完全にダウンロードされたかどうかを確認する単純なチェックサム ロジックを作成するにはどうすればよいですか?

非同期リクエストを作成して送信する方法は次のとおりです。

ASIHTTPRequest *request;
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setShouldAttemptPersistentConnection:NO]; 
[request setAllowResumeForFileDownloads:YES];
[request setDownloadProgressDelegate:self];
[request setShouldContinueWhenAppEntersBackground:YES];
[request setUserInfo:userInfo];
[request setDownloadDestinationPath:downloadPath];
[request setTemporaryFileDownloadPath:[NSString stringWithFormat:@"%@.download", downloadPath]];

[self.networkQueue addOperation:request];
[self.networkQueue go];

4 つの同時ダウンロードでネットワーク キューを使用していることに注意してください。

ありがとう。

編集 (2012 年 3 月 5 日月曜日、午後 3 時 25 分)

したがって、さらに調査すると、がではなくデリゲート メソッドをASINetworkQueue呼び出していることがわかります。オブジェクトによって返されるステータス コードはin method です。ステータス コードは です。requestDidFinishSelectorrequestDidFailSelectorASIHTTPRequest206, HTTP/1.1 206 Partial ContentrequestDidFinishSelector200, HTTP/1.1 200 OK

理由はまだわかりません!そして、私はまだこれを修正する方法を知りません。部分的にダウンロードしたファイルを削除して、ダウンロード プロセスを再度開始する必要があるようです。この時点で、一時ファイル ie%@.downloadが削除され、この部分的にダウンロードされたファイルが宛先パスに配置されます。

4

1 に答える 1

1

それで、これが私がやったことです。うまくいけば、これで十分です(問題を解決するには)。

ネットワークキューを作成する方法は次のとおりです。

- (ASINetworkQueue *)networkQueue {

    if (!_networkQueue) {
        _networkQueue = [[ASINetworkQueue alloc] init];
        [_networkQueue setShowAccurateProgress:YES];
        [_networkQueue setRequestDidFinishSelector:@selector(contentRequestDidSucceed:)];
        [_networkQueue setRequestDidFailSelector:@selector(contentRequestDidFail:)];
        [_networkQueue setShouldCancelAllRequestsOnFailure:NO];
        [_networkQueue setDelegate:self];
    }

    return _networkQueue;
}

そして、これが私のcontentRequestDidSucceed:メソッドが行うことです:

- (void)contentRequestDidSucceed:(ASIHTTPRequest *)request {
    // ASIHTTPRequest doesn't use HTTP status codes (except for redirection), 
    // so it's up to us to look out for problems (ex: 404) in the requestDidFinishSelector selector. 
    // requestDidFailSelector will be called only if there is the server can not be reached 
    // (time out, no connection, connection interrupted, ...)

    // In certain cases ASIHTTPRequest/ASINetworkQueue calls the delegate method requestDidFinishSelector,
    // instead it should call requestDidFailSelector. I've encountered this specific case with status code 206 (HTTP/1.1 206 Partial Content). In this case the file was not completely downloaded, so we'll have to re-process the request.
    if ([request responseStatusCode] != 200) {
        NSLog(@" ");
        NSLog(@"======= BEEP =======");
        NSLog(@" ");

        // We're double checking that the file was indeed not downloaded completely!
        // During internal testing, we encountered a case where download was successful
        // but we received 206 as the response code (maybe we received the cached value).
        unsigned long long progress = [request totalBytesRead] + [request partialDownloadSize];
        unsigned long long total = [request contentLength] + [request partialDownloadSize];

        if (progress != total) {
            NSString *downloadPath = [request downloadDestinationPath];
            NSString *temporaryDownloadPath = [self temporaryPathForFile:downloadPath];

            // Move the file at destination path to the temporary destination path (back again)    
            NSError *moveError = nil;
            [[[[NSFileManager alloc] init] autorelease] moveItemAtPath:downloadPath 
                                                                toPath:temporaryDownloadPath 
                                                                 error:&moveError];

            if (moveError) {
                NSLog(@"Failed to move file from '%@' to '%@'", downloadPath, temporaryDownloadPath);

                NSError *removeError = nil;
                [ASIHTTPRequest removeFileAtPath:downloadPath error:&removeError];

                if (removeError) {
                    NSLog(@"Failed to remove file from '%@'", downloadPath);
                }
            }

            // Call the requestDidFailSelector method
            [self contentRequestDidFail:request];

            // Don't continue
            return;   
        }        
    }

    // TODO: Process successful request!
    // . . .
}

これを処理するためのより良い方法があれば、私に知らせてください。

于 2012-03-07T04:46:56.960 に答える