在文档目录中读/写文件的问题

6

我正在尝试将一个非常基本的文本字符串写入我的文档目录,并从那里开始工作,以便稍后保存其他文件等。

我目前无法将任何内容写入我的文档目录

(在我的viewDidLoad中)

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray objectAtIndex:0];

NSString *textPath = [documentsDirectory stringByAppendingPathComponent:@"file1.txt"];
NSString *text = @"My cool text message";

[[NSFileManager defaultManager] createFileAtPath:textPath contents:nil attributes:nil];
[text writeToFile:textPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
NSLog(@"Text file data: %@",[[NSFileManager defaultManager] contentsAtPath:textPath]);

这是打印出来的内容:

2011-06-27 19:04:43.485 MyApp[5731:707] 文本文件数据:(null)

如果我尝试这样做,它也会打印出 null:
NSLog(@"My Documents: %@", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL]);

我在写入文件时错过了什么或者做错了什么?可能需要更改plist中的某些内容或需要一些框架/导入吗?
谢谢
[编辑] 我通过writeToFile传递了一个NSError对象并得到了这个错误:
错误:错误域=NSCocoaErrorDomain Code=512“无法完成操作。(Cocoa错误512。)”UserInfo=0x12aa00 {NSFilePath=/var/mobile/Applications/887F4691-3B75-448F-9384-31EBF4E3B63E/Documents/file1.txt,NSUnderlyingError=0x14f6b0“无法完成操作。不是目录”}
[编辑2] 这在模拟器上很好用,但在我的手机上不行 :/

1
你需要做的第一件事是查看你的写操作是否产生了任何错误。在调用 writeToFile: 时,传入一个 NSError 对象,并在调用后检查错误。 - keno
尝试使用[text writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:NULL];。这里的区别在于你正在进行原子写入。请查看苹果文档中的[NSString writeToFile:atomically:encoding:error:]以了解其背后的原因。另外,由于错误是关于目录的,所以请在设备上调试您的应用程序,以查看文件路径的实际情况。 - keno
我也尝试更改原子值,但没有任何区别。 - Pangolin
我刚刚在我的电脑和iPad上尝试了你的代码,两者都可以工作 :-/。不确定该告诉你什么,除非尝试在另一台设备上运行相同的代码并查看是否获得相同的结果。从错误来看,似乎问题是文件路径无法访问。如果您可以找到某种方式直接访问文件系统以验证结构,这可能有所帮助(以编程或其他方式)。我谷歌搜索并找到了Phone Disk。我没有尝试过,所以如果它损坏了您的设备,请不要责怪我 :) ... 如果您找到解决方案,请发布答案以帮助他人。 - keno
5个回答

2

不要使用NSFileManager来获取文件的内容,尝试使用NSString,如下所示:

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray objectAtIndex:0];
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:@"file1.txt"];
NSError *error = nil;
NSString *str = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
    NSLog(@"There was an error: %@", [error description]);
} else {
    NSLog(@"Text file data: %@", str);
}

编辑:添加了错误检查代码。


1

你是如何获取documentsDirectory的?

你应该使用类似这样的代码:

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)

NSString *documentsDirectory = [pathArray lastObject];

不,那不是问题所在。我用了那段代码(已编辑到问题中)。无论如何还是谢谢。 - Pangolin

0

您还可以使用NSFileHandle将数据写入文件并保存到文档目录:

创建一个NSFileHandle变量:

NSFileHandle *outputFileHandle;

使用prepareDataWrittenHandle函数,并将带有文件扩展名的文件名作为参数传递。
-(void)prepareDataWrittenHandle:(NSString *)filename
{
    //Create Path of file in document directory.
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:filename];

    //Check file with above name is already exits or  not.
    if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath] == NO) {
        NSLog(@"Create the new file at outputFilePath: %@", outputFilePath);

        //Create file at path.
        BOOL suc = [[NSFileManager defaultManager] createFileAtPath:outputFilePath
                                                           contents:nil
                                                         attributes:nil];
        NSLog(@"Create file successful?: %u", suc);
    }

    outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:outputFilePath];
}

然后将字符串值写入文件中:
//Create a file
[self prepareDataWrittenHandle:@"file1.txt"];

//String to save in file
NSString *text = @"My cool text message";

//Convert NSString to NSData to save data in file.
NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]

//Write NSData to file
[_outputFileHandle writeData:data];

//close the file if written complete
[_outputFileHandle closeFile];

在文件写入结束后,应该关闭文件。

您还可以检查以NSString形式编写的文件内容,以便从@Glenn Smith提到的调试角度进行检查:

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:@"file1.txt"];

NSError *error;
NSString *str = [NSString stringWithContentsOfFile:outputFilePath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
    NSLog(@"There was an error: %@", [error description]);
} else {
    NSLog(@"Text file data: %@", str);
}

0
在设置变量值的每一行后添加一个NSLog语句,以便您可以检查这些值。这应该有助于您快速确定问题出现的位置。

0
问题通过在info.plist中设置非标准Bundle ID得到解决。
我使用了iTunes Connect中此特定应用程序的Bundle ID。现在一切都运行得很完美。

1
不确定更改Bundle ID 是否有所帮助。 - Thiru
如果已经存在,则删除:if ([[NSFileManager defaultManager] fileExistsAtPath:targetPath]) { [[NSFileManager defaultManager] removeItemAtPath:targetPath error:nil]; } - Thiru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接