Получить файл из каталога в NSData

Я пытаюсь получить свой файл в созданном мной каталоге в каталоге документов в объект NSData следующим образом:

NSString *path = [documentsDirectory stringByAppendingFormat:@"%@%@",@"/",fileName];

                NSError* errorr = nil;
                NSData *fileData = [NSData dataWithContentsOfFile:path options: 0 error: &errorr];
                if (fileData == nil)
                {
                    NSLog(@"Failed to read file, error %@", errorr);
                }
                else
                {

                }

Но я всегда получаю эту ошибку:

Failed to read file, error Error Domain=NSCocoaErrorDomain Code=257 "The operation couldn’t be completed. (Cocoa error 257.)" UserInfo=0x156be110 {NSFilePath=/var/mobile/Applications/679253E3-652C-45EE-B589-609E52E4E3B0/Documents/upload/test.xml, NSUnderlyingError=0x156ba7f0 "The operation couldn’t be completed. Permission denied"}

Итак, если я проверю, читается ли файл:

if ([[NSFileManager defaultManager] isReadableFileAtPath: path]  == YES)
                    NSLog (@"File is readable");
                else
                    NSLog (@"File is read only");

я получаю результат, что файл доступен для чтения, так почему я получаю сообщение об ошибке, если я хочу разобрать этот файл в NSData?!

ОБНОВЛЕНИЕ: я создал свой файл следующим образом:

NSString *filePath = [self dataFilePath:fileName];

[xmlData writeToFile:filePath atomically:YES];

- (NSString *)dataFilePath: (NSString *) path {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                     NSUserDomainMask, YES);
NSString *documentsDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"upload"];

NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory])
    [[NSFileManager defaultManager] createDirectoryAtPath:documentsDirectory withIntermediateDirectories:NO attributes:nil error:&error];

NSString *documentsPath = [documentsDirectory
                           stringByAppendingPathComponent:path];
return documentsPath;

}

ОБНОВЛЕНИЕ 2: после создания файла я перемещаю его в другой каталог с помощью этой функции:

- (void)moveXmlFilesToUploadDirectory
{
@try {
    //Check if FILES_DIR exists
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    NSString *documentsDirectory = [[paths objectAtIndex:0]     stringByAppendingPathComponent:FILES_DIR];//filesDir
    NSString *uploadDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:UPLOAD_DIR];//filesDir

    if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory])
    {
        NSString *extension = @"xml";
        NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL];
        NSEnumerator *e = [contents objectEnumerator];
        NSString *filename;
        while ((filename = [e nextObject])) {

            if ([[filename pathExtension] isEqualToString:extension]) {
                [[NSFileManager defaultManager] moveItemAtPath:documentsDirectory toPath:[uploadDirectory stringByAppendingPathComponent:filename] error:NULL];

            }
        }
    }

}
@catch (NSException *exception) {

}
@finally {

}

}

Возможно проблема в перемещении файла! Потому что, если я попытаюсь получить свой файл в NSData, прежде чем переместить его, все будет работать...


person davidOhara    schedule 22.01.2014    source источник
comment
Можете ли вы поделиться своим documentsDirectory методом?   -  person James Frost    schedule 22.01.2014
comment
Это не метод, это путь (NSString)! Я создаю его следующим образом: NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [[пути objectAtIndex:0] stringByAppendingPathComponent:@upload];   -  person davidOhara    schedule 22.01.2014
comment
Используйте `stringByAppendingPathComponent, а не stringByAppendingFormat.   -  person Hot Licks    schedule 22.01.2014
comment
Та же ошибка, если я использую: NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@%@/, fileName]];   -  person davidOhara    schedule 23.01.2014
comment
Но вы все равно должны использовать stringByAppendingPathComponent. Вы можете получить бит, используя другую схему, и она требует ввода большего количества символов и менее эффективна.   -  person Hot Licks    schedule 23.01.2014


Ответы (2)


Кажется, вы пытаетесь скопировать весь каталог в место назначения, которое должно быть файлом. В результате путь к файлу в конце концов является путем к каталогу, поэтому вы не можете открыть его как файл, что приводит к сообщению об ошибке разрешения.

Вы должны обновить свой код копирования до

 while ((filename = [e nextObject])) {

            if ([[filename pathExtension] isEqualToString:extension]) {
                [[NSFileManager defaultManager] moveItemAtPath:[documentsDirectory stringByAppendingPathComponent: filename] toPath:[uploadDirectory stringByAppendingPathComponent:filename] error:NULL];

            }
        }

копировать каждый файл по отдельности. Это создаст фактический файл по пути назначения, предназначенному для каталога.

person Alexander Ney    schedule 23.01.2014

Велика вероятность, что у вас нет нужных прав доступа к этому файлу. Пожалуйста, проверьте разрешения и добавьте доступ на чтение для текущего пользователя или «всех». Вы можете установить права на чтение для своего пользователя в информационном диалоге (cmd + i) или в терминале с помощью chmod u+r test.xml. В конце концов вы должны установить владельца раньше с помощью

sudo chown yourusername test.xml 

Надеюсь, это имеет смысл.

person Alexander Ney    schedule 22.01.2014
comment
Вы можете использовать NSFileManager для управления правами доступа к файлам из вашего приложения. developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Reference/ просто проверьте их с помощью - (NSDictionary *)attributesOfItemAtPath:(NSString *)path error: (NSError **)error Было бы интересно узнать, как вы создали этот файл? - person Alexander Ney; 23.01.2014
comment
результат: {NSFileCreationDate = 2014-01-23 12:36:06 +0000; NSFileExtensionHidden = 0; NSFileGroupOwnerAccountID = 501; NSFileGroupOwnerAccountName = мобильный; NSFileModificationDate = 2014-01-23 12:36:06 +0000; NSFileOwnerAccountID = 501; NSFileOwnerAccountName = мобильный; NSFilePosixPermissions = 493; NSFileProtectionKey = NSFileProtectionCompleteUntilFirstUserAuthentication; NSFileReferenceCount = 2; NSFileSize = 102; NSFileSystemFileNumber = 2777322; NSFileSystemNumber = 16777219; NSFileType = NSFileTypeDirectory; } - person davidOhara; 23.01.2014
comment
каталог выглядит нормально. Как насчет вашего test.xml? - person Alexander Ney; 23.01.2014
comment
каковы атрибуты вашего файла, к которым вы пытаетесь получить доступ? И откуда оно взялось? Вы создаете его в приложении? - person Alexander Ney; 23.01.2014
comment
Я только что опубликовал атрибуты моего файла! И я обновил свой вопрос, где вы можете увидеть, как я создал этот файл! Да, это создано в приложении! - person davidOhara; 23.01.2014
comment
давайте продолжим это обсуждение в чате - person davidOhara; 23.01.2014
comment
Извините, я видел атрибуты файла для каталога developer.apple.com/library/mac/documentation/cocoa/reference/, как вы можете видеть на NSFileType = NSFileTypeDirectory; Я думал, что это был ваш каталог загрузки. Вызов метода [xmlData writeToFile:filePath атомарно:YES]; непрозрачный, поэтому я не вижу, что там происходит. Но тогда атрибуты файла неверны, потому что они явно относятся к каталогу, а не к файлу, возможно, в этом проблема. - person Alexander Ney; 23.01.2014
comment
Можно зайти в чат?! - person davidOhara; 23.01.2014