0

iOS デバイス (iPad) で大きなファイル (>200 MB) を書き込む際に問題がありますが、シミュレーターでは問題なく動作します。ファイルの作成とファイルの書き込み
に使用しています。私のコードはシミュレーターで問題なく動作するので問題ないと思います。同じ問題を抱えている人はいますか?NSFileManagerNSFileData

私の状況を詳しく説明するには:

正常に動作するデバイスにファイルのチャンク (各 3MB) を保存しています。つまり、300 MB のファイルの場合、100 個のチャンクがあります。ここで、100 個のチャンクから実際のファイルを作成します。したがってNSFileManager、最初の繰り返しでファイルを作成するために使用し、次にNSFileDataファイルの最後に 3MB のデータを書き込むために使用しています。プログラムの実行中に、61 チャンクの後にクラッシュします。iPadにメモリ関連の問題があるのではないかと推測しています。

ファイルのチャンクをfileDirdata-0、data-1、data-2 の形式で保存しています...データに復号化操作を適用していますが、簡単にするためにその部分を削除しました。

// List of chunk files        
NSArray *filelist= [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fileDir error:err];
for(int i = 0; i < [filelist count]; i++) {
                // Read the chunk of file
                fileName = [[NSString alloc] initWithFormat:@"data-%d", i];
                filePath = [fileDir stringByAppendingPathComponent:fileName];
                fileReadHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];

                // Write in tempFile
                if(offset == 0){
                    if([[NSFileManager defaultManager] createFileAtPath:tempFile contents:data attributes:nil]){
                        fileWriteHandle = [NSFileHandle fileHandleForWritingAtPath:tempFile];
                        NSLog(@"File was created!");
                    } else {
                        NSLog(@"File was not created.");
                    }
                } else {
                   [fileWriteHandle seekToEndOfFile];  // Tried with comment out this line but same problem
// Write the decrypted data from chunk
            [fileWriteHandle writeData:[[fileReadHandle readDataToEndOfFile] decryptedAES256DataUsingKey:AESEncryptionKey error:err]];
                    }
                }

編集 (11.02.2013) データの復号化部分を省略した以前のコードを試しました。興味深いことに、問題は復号化の部分にあり、復号化しなくても正常に機能すると思います。解読コードを追加しました。復号化には NSData+CommonCrypto ライブラリ (非 ARC) を使用していますが、私のプロジェクトは ARC にあります。

4

2 に答える 2

2

NSFileHandle がチャンクごとに閉じられないため、オペレーティング システムの問題である可能性があります。閉めることをお勧めします。

また、変数が for ループの範囲外で宣言されているようです。ループの外側でこれらの変数が必要でない限り、特に ARC を使用していて、いつメモリが解放されるかを考えようとしている場合は特に、変数のスコープをできるだけ小さくしておくことをお勧めします。

NSFileHandle がメモリ内のデータを保持していると思われる場合は、-synchronizeFile各チャンクを書き込んだ後にメソッドを使用して、メモリ内の変更がディスクに反映されていることを確認してください。

また、あなたが書き込んでいるファイルの作成をループの外に移動しました。

この調整を試してください:

// List of chunk files        
NSArray *filelist= [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fileDir error:err];

if([[NSFileManager defaultManager] createFileAtPath:tempFile contents:[NSData data] attributes:nil]){
    NSLog(@"File was created!");
} else {
    NSLog(@"File was not created.");
}

NSFileHandle *fileWriteHandle = [NSFileHandle fileHandleForWritingAtPath:tempFile];

for(int i = 0; i < [filelist count]; i++) {
    // Read the chunk of file
    NSString *fileName = [NSString stringWithFormat:@"data-%d", i];
    NSString *filePath = [fileDir stringByAppendingPathComponent:fileName];

    NSFileHandle *fileReadHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
    NSData *data = [fileReadHandle readDataToEndOfFile];

    // No longer using the file
    [fileReadHandle closeFile];

    // Write in tempFile
    [fileWriteHandle writeData:data];
    [fileWriteHandle synchronizeFile];// Flush any data in memory to disk
}

[fileWriteHandle closeFile];
于 2013-02-10T22:45:01.980 に答える
1

次のコードを変更すると、魔法のように機能しました。

@autoreleasepool { 
[fileWriteHandle writeData:[[fileReadHandle readDataToEndOfFile] decryptedAES256DataUsingKey:AESEncryptionKey error:err]]; 
}
于 2013-02-11T10:24:40.473 に答える