该文件是隐藏的吗?

时间:2009-07-16 20:52:59

标签: cocoa macos

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

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

我知道隐藏文件以句点为前缀。这不是隐藏文件的唯一标准。我在某处读到了一个.hidden文件,它也可以配置隐藏的文件。

有没有Cocoa / Carbon方法可以轻松找到这一点而无需重写所有这些逻辑并从各种来源收集信息?

编辑:kLSItemInfoIsInvisible检查似乎适用于某些文件。它似乎没有隐藏:

/dev
/etc
/tmp
/var

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

5 个答案:

答案 0 :(得分:5)

正如海报所指出的,它似乎不适用于/ etc和/ var而不是什么,所以我修改了方法。

现在需要“isFile”布尔值,YES表示其文件,NO表示目录

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

    }

现在似乎对所有事情都有效!

答案 1 :(得分:4)

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

几年前,我不得不写一些东西来切换给定文件的可见性,我发现它实际上比我预期的要复杂得多。它的关键是获取文件的Finder信息(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;
}

如果您需要更多信息,请参阅Apple Finder Interface上的文档。希望这会有所帮助。

答案 2 :(得分:3)

来自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直接访问/私人(使用Go To Folder菜单项),你会发现它们显示得很好。 (感谢@IlDan的提示)

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

答案 3 :(得分:2)

我认为重点是Finder是文件系统树用户的前端。如果他认为某个文件是隐藏的,你想询问 Finder ,所以你需要一个API来做这件事。

似乎LSCopyItemInfoForURL完成了工作,如其他答案所示。 This post非常有用:

  

有几种方法可以做到   被认为是不可见的(在Mac OS X下):

     
      
  • 设置了kLSItemInfoIsInvisible Finder标志
  •   
  • 文件名以句号
  • 开头   
  • 在/.hidden文件中列出
  •   
  • 由于父母身份而无形
  •   
  • 由于包
  • 而无形   

我不是一直都在复制它,它很长但很好写。

答案 4 :(得分:1)

哲学位先:

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

尽管如此,除非您正在实施文件系统浏览器,否则NSOpenPanel和朋友的内部工作通常会透明地处理相关的决定(没有双关语)。

如果您以编程方式访问文件,并且在同一文件中保留了一些相似的所有权,或者您没有在UI中显示(或不显示)文件,那么Finder认为它隐藏或者无关紧要不

技术位;因为任何应用程序都能够(通过前面提到的和古老的NSOpenPanel)来访问这些信息,所以它可能在某个地方可用;但正如已经指出的那样,这需要对CoreFoundation和LaunchServices进行一次相当迂回的研究。

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