On this page:
1 Introduction(s)
2 Purpose
3 The Structure of File Systems
Counting Files and Directories
Looking for Files and Directories
Listing Files and Directories
Looking at Files in Directories
6.12

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).

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.

Let’s make some examples. Suppose we have the following filesystem structure:

/

 DIR0/

      FILE0

 DIR1/

      FILE1

      DIR2/

           FILE2

           FILE3

           FILE4

 DIR3/

where FILE0 has the following content:

To be, or not to be: that is the question

FILE1 has the following content:

This above all: to thine own self be true

FILE2 has the following content:

It is a tale told by an idiot, full of sound and fury, signifying nothing.

FILE3 has the following content:

Some are born great, some achieve greatness, and some have greatness thrust upon 'em.

and FILE4 has no content at all.

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.