Игнорировать файлы .DS_Store и Icon в папке с Cocoa NSFIleManager

Я пытаюсь удалить определенные файлы из каталога с помощью NSFileManager. Я хотел бы игнорировать скрытые файлы .DS_Store и Icon (папка, которую я проверяю, должна иметь собственный значок), которые находятся в каталоге, однако я также продолжаю случайно удалять их. Прямо сейчас я делаю следующее:

 NSFileManager *manager = [NSFileManager defaultManager];
 NSArray *dirContents = [manager contentsOfDirectoryAtPath:[selectedFolder stringValue] error:nil]; 
 for (int i = 0; i < [dirContents count]; i++)
 {
     NSString *theFile = [dirContents objectAtIndex:i];

     if([theFile isEqualToString:@".DS_Store"] || [theFile isEqualToString:@"Icon?"] || [theFile isEqualToString:@"Icon"])
     { 
        continue;
     }
     //do manipulations on files here
 }
[manager release];

Однако файлы .DS_Store и Icon не совпадают в моем операторе if. Кроме того, когда я показываю скрытые файлы в Finder, файл значка называется «Значок». Однако выполнение ls в этом каталоге в терминале выводит «Значок?».

Как я могу правильно разобрать эти файлы в своем коде?

Спасибо

EDIT: Таким образом, на самом деле он успешно игнорирует файл .DS_Store, но файл Icon по-прежнему проходит мимо оператора if.


person minimalpop    schedule 01.05.2011    source источник
comment
Если вы пишете NSLog(@"%@", theFile); сразу после установки theFile, отображаются ли эти имена файлов значков точно так же, как вы тестируете в этом if?   -  person    schedule 02.05.2011
comment
+1 Бавария. Можно поспорить, что ?, который вы видите в Терминале, на самом деле не является ASCII-кодом ?.   -  person jscs    schedule 02.05.2011


Ответы (3)


Интересно, что я считаю, что часть question еще один недавно опубликованный вопрос по существу отвечает на ваш. Если вы используете:

-[NSFileManager contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:] 

(ссылка на документ), вы можете указать параметр NSDirectoryEnumerationSkipsHiddenFiles, чтобы игнорировать скрытые файлы, чтобы вам не приходилось проверять наличие определенных:

NSURL * selectedFolderURL = [NSURL fileURLWithPath:[selectedFolder stringValue]];
[myFileManager contentsOfDirectoryAtURL:selectedFolderURL
             includingPropertiesForKeys:[NSArray arrayWithObject:NSURLNameKey]
                                options:NSDirectoryEnumerationSkipsHiddenFiles
                                  error:&error];

Обратите внимание, что это возвращает абсолютные URL-адреса, тогда как метод в вашем вопросе возвращает пути, которые относительны к исходному каталогу. Легко обойти, но важно знать, особенно если вы удаляете материал.

person jscs    schedule 01.05.2011
comment
Этот метод возвращает URL-адреса файлов вместо путей к файлам, поэтому он требует дополнительных изменений в коде. - person Nicolas Miari; 28.01.2015
comment
[theURL path] казалось слишком очевидным, чтобы его упоминать. - person jscs; 29.01.2015
comment
Я знаю ;) В любом случае использование URL-адресов вместо путей кажется более современным и рекомендуемым способом в наши дни. - person Nicolas Miari; 29.01.2015
comment
Совершенно верно, на мой взгляд; API на основе пути в некоторых местах более ограничен. - person jscs; 29.01.2015
comment
URL-адреса определенно более мощные. Но я хотел отметить, что помимо замены NSString на NSURL старый метод возвращает массив имен файлов относительно пути к каталогу; новый возвращает полные (абсолютные) URL-адреса. Это укусило меня, пока я не узнал. - person Nicolas Miari; 29.01.2015

Имя файла ресурса пользовательского значка папки — «Icon\r» (Icon, за которым следует возврат каретки).

Что я обычно делаю при перечислении каталога, в котором я хочу пропустить невидимые элементы (те, чье имя начинается с «.»), это проверить наличие префикса @.»:

NSMutableArray *fullPaths = [NSMutableArray array];

NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];

NSArray *subpaths = [fileManager subpathsAtPath:filePath];

for (NSString *subpath in subpaths) {
   if ( ![[subpath lastPathComponent] hasPrefix:@"."] && 
        ![[subpath lastPathComponent] isEqualToString:@"Icon\r"]) {
        [fullPaths addObject:[filePath stringByAppendingPathComponent:subpath]];
   }
}
// continue

Приведенный выше код будет работать в 10.5 и более поздних версиях (или даже в 10.0, я полагаю, если вы изменили быстрое перечисление на использование NSEnumerator).

P.S. Если вы создаете NSFileManager с помощью +defaultManager, вам не следует использовать строку [manager release], так как это приведет к чрезмерному выпуску.

Итак, вместо:

NSFileManager *manager = [NSFileManager defaultManager];
// 
[manager release];

do

NSFileManager *manager = [[NSFileManager alloc] init];
//
[manager release];

or

NSFileManager *manager = [NSFileManager defaultManager];
//
person NSGod    schedule 02.05.2011
comment
Это не нужно и, возможно, опасно для того, о чем спрашивал ОП. Во-первых, subPathsAtPath: (чье использование не рекомендуется после 10.4 (см. Особые замечания)) рекурсивно работает с подкаталогами, что означает следующее: может привести к файлам, которых не в исходном каталоге. Кроме того, NSFileManager будет пропускать невидимые файлы для с помощью NSDirectoryEnumerationSkipsHiddenFiles и может предоставить вам перечислитель содержимого каталога с помощью enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:, если вы этого хотите (хотя, NB, это также рекурсивно). - person jscs; 02.05.2011
comment
Одно замечание: не каждый скрытый файл имеет имя, начинающееся с ., например. SetFile -a V /path/to/file. - person ; 02.05.2011

Простой метод:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *imageFilenames = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];

for (int i = 0; i < [imageFilenames count]; i++)
    {

    NSString *imageName = [NSString stringWithFormat:@"%@/%@",documentsDirectory,[imageFilenames objectAtIndex:i] ];

        if (![[imageFilenames objectAtIndex:i]isEqualToString:@".DS_Store"])
        {
          UIImage *myimage = [UIImage imageWithContentsOfFile:imageName];
          UIImageView *imageView = [[UIImageView alloc] initWithImage:_myimage];
        }
    }
person Rajesh Loganathan    schedule 19.11.2013