【问题标题】:File write with [NSBundle mainBundle] fails使用 [NSBundle mainBundle] 写入文件失败
【发布时间】:2016-08-28 14:55:50
【问题描述】:

我正在尝试从一个文件中获取内容并将其写入另一个文件。我读得很好,但我无法将它写入另一个文件。

我有一个单词数据库。我想根据字母的数量将单词分成不同的文件。所有四个字母的单词都放在一个文件中,依此类推。我在资源中添加了一个名为“4letter”的 txt 文件,以下是我的代码:

NSError *error;

//READ
NSString *dbFile = [[NSBundle mainBundle] pathForResource:@"words" ofType:@"txt"];
NSString *test = [NSString stringWithContentsOfFile:dbFile encoding:NSUTF8StringEncoding error:&error];

//convert from string to array
NSArray *lines = [test componentsSeparatedByString:@"\n"]; 

NSFileHandle *logFile = nil;
logFile = [NSFileHandle fileHandleForWritingAtPath:[[NSBundle mainBundle] pathForResource:@"4letter" ofType:@"txt"]];

//Test if write works
for (int i=0; i<5; i++) 
{
    NSString *randomAnagram = [[lines objectAtIndex:i] lowercaseString];
    [logFile writeData: [randomAnagram dataUsingEncoding: NSNEXTSTEPStringEncoding]];
}

【问题讨论】:

    标签: objective-c cocoa-touch ios file-io


    【解决方案1】:

    在 iOS 中,您无法写入应用程序包中的文件——整个包是只读的。请改用 Documents 文件夹的路径。

    【讨论】:

    • 文档文件夹的路径是什么?我的目标是iOS。写入后在哪里可以找到文件夹?
    • 请参阅Standard System Directories 了解如何定位 Documents 目录以及其他标准目录。
    • 要获取文档文件夹的路径,请使用: NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentsDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0];
    • 即使您可以写入捆绑包,捆绑包也不会备份,您的应用数据也会丢失。
    • 文件夹对我的数据是否安全。我想要与具有编辑功能的应用程序包相同的安全性。有可能吗?
    【解决方案2】:

    请参阅特别的File System Programming Guide 以获得更好的理解。
    在 iOS 中,您无法写入应用程序包中的文件——整个包是只读的。

    考虑阅读iOS Data Storage Guidelines,以更好地了解以下目录在 iCloud 备份上下文中的用途。

    /AppName.app

    这是包含应用程序本身的捆绑目录。不要写 这个目录的任何东西。为防止篡改,捆绑目录 在安装时签名。写入此目录会更改 签名并阻止您的应用再次启动。


    /Documents/

    使用此目录来存储重要的用户文档和应用数据 文件。关键数据是您的应用程序无法重新创建的任何数据, 例如用户生成的内容。这个目录的内容可以是 通过文件共享提供给用户。这个内容 目录由 iTunes 备份。


    /Library/

    此目录是非用户文件的顶级目录 数据文件。您通常将文件放在几个标准之一 子目录,但您也可以为文件创建自定义子目录 您想要备份但不向用户公开。你不应该使用 此目录用于存放用户数据文件。这个目录的内容 (Caches 子目录除外)由 iTunes。有关库目录的更多信息,请参阅 “库目录存储应用程序特定的文件。”

    查看iOS Standard Directories: Where Files Reside中的完整列表(tmp/、文档/收件箱)

    更新
    我使用 NSFileManager 方法URLForDirectory:inDomain:appropriateForURL:create:error:

    【讨论】:

    • 我什至阅读了这份完整的文件。我很困惑,如果我将我的 imp 文件或视频保存在文件夹中。然后它会很容易地提供给其他人。
    • 您不能像这样共享文件,因为每个文件都只能从您的应用程序中看到。要共享文档,您需要 Document Interaction Programming Guide
    【解决方案3】:

    就像 Caleb 所说,您不能写入应用的目录,但可以写入应用的 Documents 文件夹。你可以这样得到它:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    

    【讨论】:

      【解决方案4】:

      您的应用程序包是只读的。我可以看到两种方式:

      1) 写入文件夹:

      NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *path =  [myPathList  objectAtIndex:0];
      

      2) 使用 sqlite 数据库。这与 1 相同(无论如何您都必须将 db 保存在文档中),但是您使用的是 sqlite 数据库。我认为这比很多 txt 和 plist 文件要好:here's a tutorial on the topic.

      【讨论】:

        【解决方案5】:

        我使用以下代码:

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"set.txt"];
        
        NSString *data=@"Kostas";
        
        [data writeToFile:appFile atomically:YES];   
        
        NSString *myData = [NSString stringWithContentsOfFile:appFile];   
        
        NSLog(@"Data : %@ ",myData);
        

        【讨论】:

        • 这与问题中的代码有什么不同?为什么问题中的代码会失败,您的代码如何避免该问题?
        • 不同的是,我将我的文件定位到应用程序的 Documents 目录,我可以在其中写入它。问题中的代码使用只读的应用程序包。
        猜你喜欢
        • 2023-03-19
        • 2011-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 2012-03-16
        相关资源
        最近更新 更多