Lab 8: Files and Directories
1 Introduction(s)
You’ll work in labs in pairs. Find someone to work with for this first lab and introduce yourself.
Make sure at least one of you have a laptop to work on for this lab.
The two of you will work as a team to solve problems. At any time, one of you will be the Head and the other will be the Hands. The Head does the thinking and the Hands does the typing. Hands type only what the Head tells them to, but you’re free to discuss any issues that pop up. We’ll have you switch off during the lab to make sure each of you get practice problem solving, dealing with syntax, and getting finger exercises on the keyboard.
2 Purpose
In this lab, you’ll practice designing programs for self-referential data (that are not lists).
3 The Structure of File Systems
Almost every computing device that comes with persistent data storage allowing you to save your stuff, organizes that data into notions of “files” and “directories.” You’re probably fairly comfortable with this organization and have no problem navigating from, say, your home directory down many layers of nested directories within directories within directories to find some file you need.
Today we’re going to look at how to represent and operate over this kind of data.
Think for a moment about what you know about files and directories (aka folders).
Files and directories are distinct things.
Files and directories have names.
A file has data inside it (the contents of the file).
A directory has files and directories inside it.
A directory may contain an arbitrary number of files or directories inside it.
Directories may nest arbitrarily deeply.
This suggests the following data definition for representing files and directories.
(define-struct file (name content)) ; A File is a (make-file String String). ; Interp: Represents a file with a name and some arbitrary content. ; (define-struct dir (name contents)) ; A Directory is a (make-dir String LoFileOrDir)) ; Interp: Represents a named container for an arbitrary amount of files or ; directories. ; ; A LoFileOrDir is one of: ; - '() ; - (cons FileOrDir LoFileOrDir) ; A FileOrDir is one of: ; - File ; - Directory ; Interp: Either a file or directory.
Lab problem 1: Templates
Write down the template for each of File, Directory, FileOrDir, and [LoFileOrDir. Be sure to reference the file-template and the directory-template in your file-or-dir-template.
/ |
DIR0/ |
FILE0 |
DIR1/ |
FILE1 |
DIR2/ |
FILE2 |
FILE3 |
FILE4 |
DIR3/ |
To be, or not to be: that is the question |
This above all: to thine own self be true |
It is a tale told by an idiot, full of sound and fury, signifying nothing. |
Some are born great, some achieve greatness, and some have greatness thrust upon 'em. |
To get you started, here are the examples representing the root directory ROOTDIR, DIR3, DIR0, FILE4, and FILE0:
Lab problem 2: Examples
Complete the definitions to represent the example given above.
(define FILE4 (make-file "FILE4" "")) ; (define FILE3 ...) ; (define FILE2 ...) ; (define FILE1 ...) (define FILE0 (make-file "FILE0" "To be, or not to be: that is the question")) (define DIR3 (make-dir "DIR3" '())) ; (define DIR2 ...) ; (define DIR1 ...) (define DIR0 (make-dir "DIR0" (list FILE0))) (define ROOTDIR (make-dir "" (list DIR0 DIR1 DIR3)))
Counting Files and Directories
Lab problem 3: num-children
Design a function num-children that returns the number of files or directories found directly inside the given directory.
(check-expect (num-children ROOTDIR) 3) (check-expect (num-children DIR0) 1) (check-expect (num-children DIR3) 0)
Lab problem 4: num-descendents
Design a function num-descendents that returns the number of files or directories found at any level inside the given directory.
(check-expect (num-descendents ROOTDIR) 9) (check-expect (num-descendents DIR0) 1) (check-expect (num-descendents DIR1) 5)
Looking for Files and Directories
Lab problem 5: file-exists?
Design a function file-exists? that, given a directory and a string name, returns #true if a file with the given name exists inside the given directory or any of its subdirectories.
Lab problem 6: dir-exists?
Design a function dir-exists? that, given a directory and a string name, returns #true if a directory with the given name exists inside the given directory or any of its subdirectories.
Lab problem 7: file-or-dir-exists?
Design a function file-or-dir-exists? that, given a directory and a string name, returns #true if a file or directory with the given name exists inside the given directory or any of its subdirectories.
Listing Files and Directories
Lab problem 8: all-file-names
Design a function all-file-names that returns a list of file names found inside the given directory and any of its subdirectories. The order in which the file names are returned is not important.
Lab problem 9: all-dir-names
Design a function all-dir-names that returns a list of directory names found inside the given directory and any of its subdirectories. The order in which the directory names are returned is not important.
Lab problem 10: all-names
Design a function all-names that returns a list of all file or directory names found inside the given directory and any of its subdirectories. The order in which the file or directory names are returned is not important.
Looking at Files in Directories
Lab problem 11: file-size
Design a function file-size that returns the number of characters inside the content of the given file.
(check-expect (file-size FILE4) 0) (check-expect (file-size FILE0) 41) (check-expect (file-size (make-file "foo" "foo!")) 4)
Lab problem 12: dir-size
Design a function dir-size that returns the sum of the sizes of all files inside the given directory and its subdirectories.