How do I tell if a file is contained in a directory? - cocoa-touch

What's the right way to tell if a file is contained within a given directory, or a subdirectory thereof?
I want something like:
if ([directoryPath contains: filePath]) {
// file is in directory, or in a subdirectory of directory.
}
Example:
ContainerPath: /Users/sfisher/Library/Application Support/iPhone Simulator/5.1/Applications/89A57CCB-250D-4D10-B913-EA456004B431/AppName.app
Not matching: /Users/sfisher/Library/Application Support/iPhone Simulator/5.1/Applications/89A57CCB-250D-4D10-B913-EA456004B431/Documents/db/Sample Data
Matching: /Users/sfisher/Library/Application Support/iPhone Simulator/5.1/Applications/89A57CCB-250D-4D10-B913-EA456004B431/AppName.app/Samples/1
I could convert everything to strings (including appending a "/" to the container directory) and check for a string match, but it seems there should be a built-in method for this.

In principle, your underlying desire is surprising impossible. A given file path may include through symbolic or hard links, making "containment" a very complicated question. These kinds of links are uncommon in iOS, but iOS is still Unix, and in Unix such things are legal.
So your real question is actually whether one path specifier (string) is contained in another. So checking the paths as strings is the correct approach.

I think a simple string match is the right way to do it:
if (![directoryPath hasSuffix:#"/"]) directoryPath = [directoryPath stringByAppendingString:#"/"];
if ([filePath hasPrefix:directoryPath]) {
// ...
}
Note that this doesn't deal with complications introduced by symlinks, or with relative paths.

Related

Filepath lastPathComponent from HFS or POSIX path

I am on OSX, not iOS, Objective-C
I receive external input like this and i need to get the file.
Case A (posix path): "path/to/afile.extension"
Case B (HFS path): "path:to:afile.extension"
In Case A i can get the file with
[path lastPathComponent];
In Case B i can get it via
[[path componentsSeparatedByString:#":"] lastObject];
Unfortunately i don't know if the input is of type A or B. What would be the best way to identify if the delivered path is a posix path or a HFS path?
What would be the best way to identify if the delivered path is a posix path or a HFS path?
Off-the-top-of-my-head: I don't think you can do this trivially based on the string as the POSIX path separator, '/', is a valid in a HFS file name, and vice-versa. E.g. the POSIX path fragment:
... Desktop/a:colon.txt
and the HFS path fragment:
... Desktop:a/colon.txt
refer to the same file.
What you could do instead is check if the path exists using file manager (NSFileManager) calls - these take HFS paths - and the access(2) system call - which takes a POSIX path. If only one of these works you know the type of path you have, if both work you've got some unusually named disks and files and the path is ambiguous! (And if neither work the path is invalid interpreted either way.)
You can also do checks by creating a file NSURL from the path and if successful then calling NSURL methods to check for existence.
Update
Your comment states that the files do not exist so checking for existence will obviously fail. So think about examining the path to work it out, only producing an error for ones you cannot figure out. E.g.:
If a path contains only '/' or ':' delimiters you can determine POSIX or HFS
A full HFS path always starts with the volume name followed by a colon. Determine the mounted volume names and check those against the path you have, if there is a match for one you have a HFS path
Etc.
For checking for characters in a string, volume names, etc. start with the NSString, NSFileManager and NSURL documentation. Once you've built up your series of tests if you have any problems etc. ask a new question describing your tests, showing your code, etc. and someone will undoubtedly help you.
HTH

Mod-Rewrite to variable ending file

I'm trying to get apache to serve any request for /uploaded/2 with the first file that starts with 2 in a certain directory (say /foo/bar/).
Basically, If I have directory /foo/bar with contents:
1-filenameclutter.wav
2-clutterinthefilename.mp3
3-someweirdtext.jpg
And a web browser makes a request for /uploaded/1, apache would return 1-filenameclutter.wav; a request for /uploaded/2 would return 2-clutterinthefilename.mp3; etc. (all files with the right mime-type).
As far as I can see, ModRewrite can only go from a source with extraneous data to a simplified file on the file system, not the other way around.
Do you guys know any way to do this, with ModRewrite or using apache in another way (no PHP)?
EDIT:
Two things to point out, 1) I'm not concerned with duplicate files starting with the same id. These files correspond to an object in a database, which has a primarykey, id. 2) The reason I'm doing this is because I won't know exactly what the extension of the file is, but I do know the id, so when I form these I just prepend the orignal filename to the end of {{id}}- (Don't worry, I replace all ".."'s with "~").
Mod-rewrite has the ability to check if a single specific file exists, but you can't search a directory for a file pattern. Note that what you are suggesting would have horrible scaling attributes because the system would have to search all the files to find the file you are looking for. Since you already have the file in the database, why don't you just name the file with the id and keep the real filename in the database? In that case, /uploaded/2 would return the file at that location. You don't even need mod_rewrite.

CMake: Get the complete representation of a path minus relative elements

I want to take a variable that has been set to a combination of path elements (potentially both absolute and relative) and get the absolute path from it. Something like what boost::filesystem::system_complete() does in C++. For example, I have something like:
set(EXTERNAL_LIB_DIR "${CMAKE_SOURCE_DIR}/../external" CACHE PATH "Location of externals")
which works but in the UI it's a bit ugly, as it might end up looking like C:/dev/repo/tool/../external. I'm wondering if there's a CMake built-in command to turn that into C:/dev/repo/external before I go and script a macro to do it. find_path kind of does this, but it requires that the path already exist and something worth searching for be there. I want it to work whether the path exists or not (I might use it for an overridden CMAKE_INSTALL_PREFIX default, for example).
You can use:
get_filename_component(NEW_VAR ${EXTERNAL_LIB_DIR} REALPATH)
As of CMake 3.20, you can use the cmake_path command to normalize the path, which supersedes the get_filename_component command.
cmake_path(SET MY_NEW_PATH NORMALIZE ${EXTERNAL_LIB_DIR})
This also converts any backslashes (\) into forward-slashes cleanly.

Parse M3U file locations to fully qualified paths

I would like to parse the file location information in an M3U playlist into fully qualified paths. The possible formats in M3U files seem to be:
c:\mydir\songs\tune.mp3
\songs\tune.mp3
..\songs\tune.mp3
For the first example, just leave it alone. For the second add the directory that the playlist resides in so it would become c:\playlists\songs\tune.mp3 and the same for the third case so it would also become: c:\playlists\songs\tune.mp3.
I'm using vb under VS2008 and I can't find a way to recognise each of the potential location formats in the M3U file. System.IO.Path offers no solution that I can find. I've searched extensively for terms like "convert relative path to absolute" but no luck.
Any advice appreciated.
Thanks.
Write a batch script that just reads the m3u file line by line, and then just parse each line looking for ":" , and for "..", and edit the string as needed. You can then just write the "converted" strings to another file...

fileExistsAtPath: (NSFileManager)

Is this method supposed to take a path as its argument?
It looks like it takes a filename as a path:
For example, /home/file.txt is a file, while /home/ is a path. This method looks like it takes the former as an argument.
Your distinction of "path" vs. "file" is not one that is common in Unix. Whether the final element of a path is a file or not doesn't affect the fact that it is a path. "/home/file.txt" looks like an absolute file path (though it could in fact be a deceptively named directory). "/home/" is an absolute directory path. Both are paths. (So is "foo/bar" — would you call that a "file" or a "path" in your terminology? Without inspecting the object at that path, we can't know whether it names a directory or a file.) Apple is using the term in its normal sense.
Yes, it takes a string that is a path - see the documentation:
Parameters
path
The path of a file or directory. If path begins with a tilde (~), it must first be expanded with stringByExpandingTildeInPath, or this method returns NO.
Note that /home/file.txt is a path, just like /home/. The former however is no directory, while the latter is.
If you're wanting to look for distinctions between files and folders, see -fileExistsAtPath:isDirectory:.
Usage:
BOOL isDirectory;
if ([self fileExistsAtPath:#"/Users/me/Subfolder" isDirectory:&isDirectory] && isDirectory)
{
// Exists and is a directory. Isn't that neat?
}