2012-05-08 4 views
3

サーバーから大きなファイルをダウンロードし、50個のパケットごとにチェックサムをチェックしてから、それらを一緒にステッチする既存のコードをクリーンアップしようとしています。私はそれがメモリの問題のためにしばらくの間クラッシュするように、これが最も効率的な方法であるかどうかを見るためにいくつかの問題を抱えています。私がチェックサムを持っていなければ、クラッシュするようなことはありませんが、最初にファイルをチェックできれば好きです。iOSアプリケーションで大きなファイルをダウンロードする

@property (nonatomic, retain) NSMutableData * ReceivedData; 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 

NSData *sequencePacketData = [[NSData alloc] initWithData:self.ReceivedData]; 
     [self ProcessPacket:sequencePacketData]; 
     [sequencePacketData release]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:DownloadNotification object:self]; 

} 

- (void)ProcessPacket:(NSData *)sequencePacketData { 
    // find the directory I need to write to and the name of the file 
NSString *currentChecksum = [WebServiceManager MD5CheckSumForNSData:sequencePacketData]; 
    BOOL checkSumValid = [dmgr ValidateChecksum:currentChecksum againstFileName:self.CurrentFileName]; 
    self.IsSuccessful = checkSumValid; 

    if (!checkSumValid) { 
     // log error msg 
     return; 
    } 

    if (success) 
    { 
     NSFileHandle *handle = [NSFileHandle fileHandleForUpdatingAtPath:sequencePath]; 
     [handle seekToEndOfFile]; 
     [handle writeData:sequencePacketData]; 
     [handle closeFile]; 
    } 
    else 
    { 
     [sequencePacketData writeToFile:sequencePath atomically:YES]; 
    } 

    // When file is completely downloaded, check the checksum of the entire file: 
BOOL completeFileCheckSum; 
    if ([packetFile isEqualToString:@"50.bin"]) { 
     NSData *temData = [NSData dataWithContentsOfFile:sequencePath]; 
     currentChecksum = [WebServiceManager MD5CheckSumForNSData:temData]; 
     completeFileCheckSum = [dmgr ValidateChecksum:currentChecksum againstFileName:fileName]; 
     NSLog(@"Checksum for whole file is valid: %i", completeFileCheckSum); 
     if (!completeFileCheckSum) { 
      NSError *err; 
      [fileManager removeItemAtPath:sequencePath error:&err]; 

      // log error 
      return; 
     } 
    } 
} 

+ (NSString*)MD5CheckSumForNSData:(NSData *) input 
{ 
    // Create byte array of unsigned chars 
    unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH]; 

    // Create 16 byte MD5 hash value, store in buffer 
    CC_MD5(input.bytes, input.length, md5Buffer); 

    // Convert unsigned char buffer to NSString of hex values 
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; 
    for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) 
     [output appendFormat:@"%02x",md5Buffer[i]]; 
    return output; 
} 

check checksum againstFileメソッドは、一時ファイルからチェックサムを取得して比較するだけです。

私はNSAutoReleasePoolsについて読んでいます。イメージの束を読み込んでメモリなどをクリアする必要がある場合はどのように役立ちますか?実際にここに当てはまるかどうかは分かりません。大きなファイル(1 GB未満)をダウンロードしてください。ありがとう!

答えて

6

多くのデータを一度にメモリに保存することは間違いなく問題になります。幸運なことに、データをディスクに書き込むことができます。また、実行中のチェックサムを保持することもできます。

展覧会新しいアイバーズのカップルのためのあなたのReceivedDataは:

NSFileHandle* filehandle; 
MD5_CTX md5sum; 

MD5_CTXはまだiOSの上でされていない...、OpenSSLの中にいるのですか?ガー。 MD5のソースはオンラインで見つけることができます。ここでは:http://people.csail.mit.edu/rivest/Md5.c(私はもともとあなたのプロジェクトにOpenSSLを追加することを提案しましたが、それはあなたが必要としない余分なジャンクですが、OpenSSLを既に使用している場合はMD5の機能が含まれています)。

- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response 
{ 
    MD5Init(&md5sum); 

    filehandle = [[NSFileHandle filehandleForWritingAtPath:path] retain]; 
} 

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data 
{ 
    MD5Update(&md5sum, [data bytes], [data length]); 

    [filehandle writeData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection*)connection 
{ 
    MD5Final(&md5sum); 
    // MD5 sum is in md5sum.digest[] 

    [filehandle closeFile]; 

    // verify MD5 sum, etc.. 
} 

最後に、あなたのファイルはディスク上にあります。あなたはそのMD5の合計を持っています。ほとんどすべてのメモリを使用しています。

+3

実際には、タイプと機能が 'CC_MD5_CTX'、' 'CC_MD5_Init''、' 'CC_MD5_Update''、' 'CC_MD5_Final'であるので、' #import 'にあります。 – NebulaFox

+1

ヘッダーファイルはhttp://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/CommonCrypto/CommonDigest.h – NebulaFox

+0

こちらをご覧ください。ありがとう! – davehayden

関連する問題