CPS 108, Spring 2003, Scandir FAQ

  1. Feb 12. To initialize a File to either a file or a directory you'll need to use a DirStream object from which you obtain a DirEntry object. Unless you muck with the internals of these classes, the only way to get a DirEntry object is via DirStream iterators. If you specify a filename of
       "foo.cpp"
    
    for example, the assumption should be that this is in the current directory, named ".", and that's the directory to open a DirStream for, then iterate looking for "foo.cpp".

    If you specify a filename of

       "108/code/coolstuff/foo.cpp"
    
    then presumably the directory is "108/code/coolstuff/" and the filename is foo.cpp. Again, open a DirStream object and iterate looking for foo.cpp. This approach works, it requires iterating a directory for a filename [of course if the user passes a directory name, then no iteration is needed].

    You can use the DirStream::fail() member function to determine if opening/constructing a DirStream succeeds. If the open fails, the probably the user has specified a file. You can strip off everything after the last "/" as the filename and everything before the last "/" as the directory name.

    The string function rfind is useful for this, the code below should print 10, the index of the last slash.

    string name = "foo/barbie/ick.cpp"; unsigned int slashPos = name.rfind("/"); if (slashPos != string::npos) { cout << "found last slash at " << slashPos << endl; } else { cout << "last slash found at " << slashPos << endl; }

    The key idea here is that to get a DirEntry object for a file, you must iterate over the directory in which the file is located. There's no other way to do this using DirStream and DirEntry classes provided. You can certainly get the file directly by exploiting the implementation of the DirStream and DirEntry classes, but who wants to do this?

    Iterate my friends

  2. Feb 12. What to do about making pointers to DirEntry objects when DirStream returns an object (not a pointer) and we don't want to use the address-of & operator?

    Use the default copy constructor which will work, e.g.,

    DirStream dirs; ... DirEntry * entry = new DirEntry(dirs.Current()); // copy it

    dirptr.cpp shows this approach.

  3. Feb 12. The class File you develop should look remarkably similar to the java.io.File class mentioned in the assignment and discussed in class, but should have far fewer methods. Specifically, you should have some function equivalent to listFiles. If a File object represents a directory, listFiles should return a list of all the entries in the directory. You can decide what listFiles should return in the case that a File object is a plain-file, i.e., not a directory. In that case you could, for example, return an empty list/vector or, alternatively, throw an exception.

    The listFiles function is the function that will approximate the functionality of the scandir functions shown in the assignment.


Owen L. Astrachan
Last modified: Thu Feb 13 20:24:49 EST 2003