1
NSFileManager* fileManager = [NSFileManager defaultManager];
NSURL* url = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
NSString* directory = [url path];
NSString* filePath = [directory stringByAppendingPathComponent:FILE_NAME];
if ([fileManager fileExistsAtPath:filePath])
{
    [fileManager removeItemAtPath:filePath error:nil];
}   

これが私のコードです。実行されると、ファイルは削除されますが、スペースは占有されたままになります。これがファイルに何かを保存するためのコードです。

NSFileManager* fileManager = [NSFileManager defaultManager];
NSURL* url = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
NSString* directory = [url path];
NSString* filePath = [directory stringByAppendingPathComponent:FILE_NAME];
NSArray* oldArray = nil;
if ([fileManager fileExistsAtPath:filePath])
{
    oldArray = [[NSArray alloc] initWithContentsOfFile:filePath];
    [fileManager removeItemAtPath:filePath error:nil];
}
NSMutableArray* mergeArray = [[NSMutableArray alloc] initWithArray:arrayOfPersons];
[mergeArray addObjectsFromArray:oldArray];
if ( [mergeArray writeToFile:filePath atomically:YES]) NSLog(@"Written");

ちなみに、オブジェクトが1つだけの配列(2つのキーを持つNSDictionary)を格納するには1MBかかります。それを保存するためのより安い方法はありますか?

4

3 に答える 3

2

実験にはもっと注意する必要があります。UNIXファイルシステムは、ファイルを使って多くのことを行います。実際、ファイルを「削除」するときは、ファイルシステムからファイルのリンクを解除するだけです。そのファイルがOSのどこかで別のファイル記述子で開かれている場合、そのファイルは開いたままになります。

さらに、ファイルノードを再利用するための最適化がたくさんあります。ファイルを削除したからといって、スペースが自動的に戻るわけではありません。他のファイルを使用するために、いくつかの理由でアプリに「予約」されている可能性があります。ファイルシステムがそれを必要とするまで、それをファイルシステムに返す意味はありません。

settings->general->usageこれは、ファイルシステムの使用率の非常に大まかな測定値です。より良い測定は、ファイルとファイルシステムの属性に直接アクセスすることです。

コードをベースとして使用して、次のことを考慮してください。

- (NSString*)workingDirectory {
    NSFileManager* fileManager = [NSFileManager defaultManager];
    NSURL* url = [[fileManager URLsForDirectory:NSCachesDirectory
                                      inDomains:NSUserDomainMask] lastObject];
    return [url path];
}

- (NSString*)filePath {
    return [[self workingDirectory] stringByAppendingPathComponent:FILE_NAME];
}

これで、ファイルシステム全体のすべての属性を次のように確認できます。

NSDictionary *attributes = [[NSFileManager defaultManager]
    attributesOfFileSystemForPath:[self workingDirectory] error:0];
NSLog(@"file system attributes: %@", attributes);

そしてこれを持つ特定のファイルのためのもの:

NSDictionary *attributes = [[NSFileManager defaultManager]
    attributesOfItemAtPath:[self filePath] error:0];
NSLog(@"file attributes: %@", attributes);

とに注意しNSFileSystemFreeSizeNSFileSizeください。

アプリを実行し、これらの値の両方をダンプします。ファイルを作成し、再度ダンプします。ファイルを削除して、再度ダンプしてください。

その後NSFileSystemFreeSize、削除した後でも、実際に上昇が見られる場合があります。システム自体が一時ファイルを作成しており、将来使用するためにそれらのファイルシステムノードをキャッシュしている可能性があることを忘れないでください。

他のすべてのアプリを終了すると、より一貫した結果を得ることができます。次に、終了します(電源ボタンをダブルクリックし、実行中のすべてのアプリをX回クリックします)。これを行う前にファイルを削除してください。

  1. 次に、ファイルを存在させずにアプリを起動します。

  2. ファイルシステムデータをダンプします。

  3. ファイルを作成します。

  4. ファイルシステムデータをダンプします。

  5. ファイルデータをダンプします。

ファイルが約200〜250バイトを占めるのがわかり、ファイルシステムの空きサイズは8192になるはずです。

  1. ファイルを削除します。

  2. ファイルシステムデータをダンプします。おそらく、ファイルを削除する前と少なくとも同じ大きさです。

  3. アプリを終了します(XCodeにはありません-電源をダブルクリックし、アプリをXにします)。

  4. アプリを実行します。

  5. ファイルシステムデータをダンプします。以前に開始したときのデータが表示されます。


結論として、ファイルシステムがデータをリリースしていないように見えるかもしれませんが、実際にはリリースしていますが、クエリに使用しているツールがファイルシステムの詳細を知らない可能性があります。

また、アプリが実行されているときは、明示的に行っていないことのために多くのファイルシステムリソースを使用することにも注意してください。

私はそれが理にかなっていることを願っています...

于 2012-09-08T00:27:54.273 に答える
0

ファイルを削除するコードは正しいように見えますが、必要のないときにURLとパスを切り替えています。また、ファイルを削除しようとしたときにエラーがないかどうかを確認して、ファイルが機能しない理由を確認する必要があります。これを試して:

    NSFileManager   *fileManager    = [NSFileManager defaultManager];
    NSArray         *directoryURLs  = [fileManager URLsForDirectory:NSCachesDirectory 
                                                          inDomains:NSUserDomainMask];
    NSURL           *directoryURL   = [directoryURLs objectAtIndex:0];
    NSURL           *fileURL        = [directoryURL URLByAppendingPathComponent:FILE_NAME];
    if (!fileURL)
    {
        NSLog(@"Could not create URL for file.");
        return;
    }

    NSError *err = nil;
    if (![fileURL checkResourceIsReachableAndReturnError:&err])
    {
        NSLog(@"File is not reachable.\n"
               "Error: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return;
    }

    err = nil;
    [fileManager removeItemAtURL:fileURL error:&err];
    if (err)
    {
        NSLog(@"Unable to delete existing file.\n"
              "Error: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return;
    }
于 2012-07-27T09:23:29.253 に答える
0

˚FILE_NAME`の長さが300文字以上である可能性がありますか?これにより、少し前にNSFileManagerで同様の問題が発生しました...

于 2012-09-06T16:30:52.303 に答える