代码之家  ›  专栏  ›  技术社区  ›  rein

文件是否隐藏?

  •  4
  • rein  · 技术社区  · 16 年前

    如何确定某个路径是否指向隐藏的文件/文件夹?

    NSString *file = @"/my/file/some.where";
    BOOL fileIsHidden = // <-- what do I do here?
    

    我知道隐藏文件的前缀是句点。这不是隐藏文件的唯一条件。我在某个地方读到了一个.hidden文件,它还配置了隐藏的文件。

    有没有一种可可/碳的方法可以很容易地发现这一点,而无需重写所有这些逻辑,并从各种来源收集信息?

    编辑:klsiteminfoisinvisible检查似乎对某些文件有效。它似乎没有隐藏:

    /dev
    /etc
    /tmp
    /var
    

    默认情况下,所有这些都被finder隐藏。

    5 回复  |  直到 16 年前
        1
  •  5
  •   micmoo    16 年前

    正如海报所指出的,它似乎不适用于/etc和/var以及不适用的内容,所以我修改了这个方法。

    它现在采用“isfile”布尔值,是表示它是一个文件,否表示一个目录。

    BOOL isInvisible(NSString *str, BOOL isFile){
            CFURLRef inURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)str, kCFURLPOSIXPathStyle, isFile);
            LSItemInfoRecord itemInfo;
            LSCopyItemInfoForURL(inURL, kLSRequestAllFlags, &itemInfo);
    
            BOOL isInvisible = itemInfo.flags & kLSItemInfoIsInvisible;
            return (isInvisible != 0);
        }
    
        int main(){
               NSLog(@"%d",isInvisible(@"/etc",NO)); // => 1
               NSLog(@"%d",isInvisible(@"/Users",NO)); // => 0
               NSLog(@"%d",isInvisible(@"/mach_kernel",YES)); // => 1
    
        }
    

    现在看来一切都很顺利!

        2
  •  4
  •   hbw    16 年前

    据我所知,OS X上的隐藏文件由前缀为句点的文件名或由查找程序跟踪的特殊“不可见”位决定。

    几年前,我不得不写一些改变给定文件可见性的东西,我发现它实际上比我预期的要复杂得多。关键是要获得一个查找器信息( FInfo )记录文件并检查 kIsInvisible 位已设置。这是我为切换文件可见性而编写的方法,我认为很多方法都与您手头的任务有关,尽管您显然需要稍微调整一下。

    - (BOOL)toggleVisibilityForFile:(NSString *)filename isDirectory:(BOOL)isDirectory
    {
        // Convert the pathname to HFS+
        FSRef fsRef;
        CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)filename, kCFURLPOSIXPathStyle, isDirectory);
    
        if (!url)
        {
            NSLog(@"Error creating CFURL for %@.", filename);
            return NO;
        }
    
        if (!CFURLGetFSRef(url, &fsRef))
        {
            NSLog(@"Error creating FSRef for %@.", filename);
            CFRelease(url);
            return NO;
        }
    
        CFRelease(url);
    
        // Get the file's catalog info
        FSCatalogInfo *catalogInfo = (FSCatalogInfo *)malloc(sizeof(FSCatalogInfo));
        OSErr err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, catalogInfo, NULL, NULL, NULL);
    
        if (err != noErr)
        {
            NSLog(@"Error getting catalog info for %@. The error returned was: %d", filename, err);
            free(catalogInfo);
            return NO;
        }
    
        // Extract the Finder info from the FSRef's catalog info
        FInfo *info = (FInfo *)(&catalogInfo->finderInfo[0]);
    
        // Toggle the invisibility flag
        if (info->fdFlags & kIsInvisible)
            info->fdFlags &= ~kIsInvisible;
        else
            info->fdFlags |= kIsInvisible;
    
        // Update the file's visibility
        err = FSSetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, catalogInfo);
    
        if (err != noErr)
        {
            NSLog(@"Error setting visibility bit for %@. The error returned was: %d", filename, err);
            free(catalogInfo);
            return NO;
        }
    
        free(catalogInfo);
        return YES;
    }
    

    这是苹果公司关于 Finder Interface ,如果您需要更多信息。希望这有帮助。

        3
  •  3
  •   BJ Homer    16 年前

    http://forums.macosxhints.com/archive/index.php/t-22641.html :

    BOOL isInvisibleCFURL(CFURLRef inURL)
    {
      LSItemInfoRecord itemInfo;
      LSCopyItemInfoForURL(inURL, kLSRequestAllFlags, &itemInfo);
    
      BOOL isInvisible = itemInfo.flags & kLSItemInfoIsInvisible;
      return isInvisible;
    }
    

    更新

    啊哈!/etc、/tmp和/var都是不可见的,因为它们实际上是指向/private/etc、/private/tmp和/private/var的符号链接。如果告诉finder直接访问/private(使用“转到文件夹”菜单项),您将看到它们显示得很好。(多亏了@ildan的小费)

    我不知道处理这个问题的最佳方法是什么;只有当你有一个到隐藏文件夹中的文件的可见符号链接时,这才重要。您可能只需手动排除进入/private的符号链接就可以逃脱处罚,但如果现在,您可能需要检查路径上每个文件夹的隐藏状态。

        4
  •  2
  •   IlDan    16 年前

    我认为关键是finder是面向文件系统树用户的前端。你想问 取景器 如果他认为某个文件是隐藏的或者不是隐藏的,那么您需要一个API来实现这一点。

    似乎lscopyiteminfoforurl可以完成这项工作,如其他答案所示。 This post 非常有用:

    有几种方法可以让事情变得 视为不可见(在Mac OS X下):

    • 已设置klsiteminfoisinvisible finder标志
    • 文件名以句点开头
    • 在/.hidden文件中列出
    • 因父母关系不可见
    • 由于包而不可见

    我不是全部抄袭,它很长,但写得很好。

        5
  •  1
  •   Williham Totland    16 年前

    哲学比特优先:

    没有文件是 事实上 隐藏的。finder维护自己的内部数据,以确定文件是否应显示在目录列表中;此信息可以与系统上的其他应用程序共享。

    但是,除非您正在实现一个文件系统浏览器,否则相关的确定通常是由 NSOpenPanel 和朋友们。

    如果您以编程方式访问一个文件,并且您对同一个文件保持一些所有权的外观,或者您没有在UI中显示该文件(或不显示),那么finder是否认为它是隐藏的并不重要。

    至于技术位,因为任何应用都可以 NSPEN面板 )要访问这些信息,它可能在某个地方可用;但是正如已经指出的,这需要对corefoundation和launchservices进行一个相当迂回的小研究。

    真正的问题可能是你是否需要知道。