What does the /private prefix on an iOS file path indicate?

前端 未结 6 895
孤城傲影
孤城傲影 2020-12-14 15:34

I have a bug when my app runs on the iPhone but not when it runs on the simulator. I was using the length of the home directory path to extract the relative path of a file

相关标签:
6条回答
  • 2020-12-14 15:45

    In Swift 3, URL has the standardizedFileUrl property, which will remove any symlinks and resolve relative parts within the path like ./.

    As of writing the documentation is pretty useless but it looks like it is equivialent to NSURL's standardized property.

    0 讨论(0)
  • 2020-12-14 15:49

    /var is just a symlink to /private/var. So the first path is the logical path that you tried to access. The second is that same path with symlinks expanded.

    0 讨论(0)
  • 2020-12-14 15:55

    A function (Swift 5) to remove an file from cache. I had a lot of problems and the use of the URL solved the /private issue.

    class func removeFileFromCache( filePattern: String ) -> Bool {
        // find filename with pattern
         
        do {
            let cachePath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
            let filePathUrl = URL( fileURLWithPath: filePattern )
            let originalFilename = filePathUrl.lastPathComponent
            let newFilePath = cachePath.appendingPathComponent( originalFilename ).path
           
            try FileManager.default.removeItem(atPath: newFilePath )
            print("file \( filePattern ) succesfull removed.",classname:URL(fileURLWithPath: #file).lastPathComponent )
            
        } catch let error as NSError {
            print("Error \(error)",classname:URL(fileURLWithPath: #file).lastPathComponent )
            return false // all is not well
        }
        
        return true
    }
    
    0 讨论(0)
  • 2020-12-14 15:57

    To actually answer your question:

    I believe /private was a prefix added when they released OS X (I don't think it was there in NeXTStep, but it's been decades). It seems to exist to house etc, var, and tmp (and, oddly, tftpboot; I didn't know my PBG4 could do that), perhaps so users don't wonder what this silly folder called etc is and try to delete it.

    On device, Apple decided to store user data in /private/var/mobile (the username is "mobile"). I'm not sure why they didn't pick /Users/mobile or just /mobile, but it has no more significance than /var/mobile would on a "normal" Unix.

    On the simulator, your user account can't write to /var (for good reason). User data is stored somewhere in ~/Library/Application Support/iPhone Simulator. At one point, they started using different directories for different simulator versions.

    0 讨论(0)
  • 2020-12-14 16:03

    I tried this from the debugger and discovered that URLByResolvingSymlinksInPath "fixes" the /private/ addition.

    (lldb) p (NSURL *)[NSURL fileURLWithPath:@"/private/var" isDirectory:YES]
    (NSURL *) $1 = 0x1fd9fc20 @"file://localhost/private/var/"
    (lldb) po [$1 URLByResolvingSymlinksInPath]
    $2 = 0x1fda0190 file://localhost/var/
    
    (lldb) p (NSURL *)[NSURL fileURLWithPath:@"/var" isDirectory:YES]
    (NSURL *) $7 = 0x1fd9fee0 @"file://localhost/var/"
    (lldb) po [$7 URLByResolvingSymlinksInPath]
    $8 = 0x1fda2f50 file://localhost/var/
    

    as you can see, file://localhost/var is what we really want here.

    Because of this, it seemed obvious that /private/var is a symlink to /var. However, @Kevin-Ballard points out that is not true. I confirmed that he is correct, and /var is the symlink to /private/var (sigh)

    (lldb) p (NSDictionary *)[[NSFileManager defaultManager] attributesOfItemAtPath:@"/var" error:nil]
    (NSDictionary *) $3 = 0x1fda11b0 13 key/value pairs
    (lldb) po $3
    $3 = 0x1fda11b0 {
        ...
        NSFileType = NSFileTypeSymbolicLink;
    }
    
    (lldb) p (NSDictionary *)[[NSFileManager defaultManager]   attributesOfItemAtPath:@"/private/var" error:nil]
    (NSDictionary *) $5 = 0x1fda4820 14 key/value pairs
    (lldb) po $5
    $5 = 0x1fda4820 {
        ...
        NSFileType = NSFileTypeDirectory;
    }
    

    So URLByResolvingSymlinksInPath is doing something funny here, but now we know. For this particular problem, URLByResolvingSymlinksInPath still sounds like a good solution that works for both the simulator and the device and should continue to work in the future if something changes.

    0 讨论(0)
  • 2020-12-14 16:10
    1. In my case while using FileManager.default.fileExists to check whether the file already exists but i was using .absoluteString/"()". instead of .path for passing URL as String.
    2. When i printed the paths of the files in Documents Directory using

    let fileURLs = try fileManager.contentsOfDirectory(at:

    it printed as /private/var

    let DocumentDirURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

    it printed as /var

    1. This difference in path made me confused.
    2. As explained Above its just symlink. ie both the paths are same.

    :)

    0 讨论(0)
提交回复
热议问题