#lang scheme ; a path is: ; - a file (contains file-size) ; - a link [symbolic link, shortcut, alias] ; - a directory (contains list-of-paths) ; Some example calls to drscheme's file-system library: ; (current-directory (string->path "/Users/ibarland/Documents/Classes/ITEC380")) (define cwd (current-directory)) cwd (directory-exists? cwd) (file-exists? cwd) (link-exists? cwd) (directory-list cwd) ; Template methods to handle our data (path, and list-of-paths): #;(define (fun-for-file-item p) (cond [(link-exists? p) ...] [(file-exists? p) ...(file-size p)...] [(directory-exists? p) ...(fun-for-lops (prefix-all p (directory-list p)))...])) #;(define (fun-for-lops lops) (cond [(empty? lops) ...] [(cons? lops) ...(first lops) ...(fun-for-lops (rest lops))])) ;;;;;;;;;;;;;;;;;;;;;;; Version 1: follow the template exactly ;;;;;;;;;;;;;;;; ; total-size : (-> path int) ; Return the p's total disk-size (including all files beneath it, if a dir). ; This doesn't count the (OS-specific) size occupied by the dir itself. ; (define (total-size-v1 p) (cond [(link-exists? p) 0] [(file-exists? p) (file-size p)] [(directory-exists? p) (size-of-many-v1 (map (lambda (f) (build-path p f)) (directory-list p)))])) ; size-of-many : (-> (list-of path) int) ; Return the total disk size used by all the paths in lops. ; (define (size-of-many-v1 lops) (cond [(empty? lops) 0] [(cons? lops) (+ (total-size-v1 (first lops)) (size-of-many-v1 (rest lops)))])) ; prefix-all : (-> pathname (list-of pathname) (list-of pathname)) ; For every path in relative-paths, prepend dir-path to the front of it. ; This is handy for taking the results of 'directory-list' ; (define (prefix-all dir-path relative-paths) (cond [(empty? relative-paths) empty] [(cons? relative-paths) (cons (build-path dir-path (first relative-paths)) (prefix-all dir-path (rest relative-paths)))])) ;;;;;;;;;;;;;;;;;;;;;;; Version 2: use map instead of calling prefix-all ;;;;;;;;;;; ; total-size-v2 : (-> path int) ; Just like -v1, but call 'map' instead of 'prefix-all'. ; (define (total-size-v2 p) (cond [(link-exists? p) 0] [(file-exists? p) (file-size p)] [(directory-exists? p) (size-of-many-v2 (map (lambda (f) (build-path p f)) (directory-list p)))])) ; size-of-many-v2 : (-> (list-of path) int) ; This is *exactly* the same as size-of-many-v1 ; (except that it calls -v2, rather than -v1, of course.) ; (define (size-of-many-v2 lops) (cond [(empty? lops) 0] [(cons? lops) (+ (total-size-v2 (first lops)) (size-of-many-v2 (rest lops)))])) ;;;;;;;;;;;;;;;;;;;;;;; Version 3: use foldr instead of calling size-of-many ;;;;;;;;;;; ; Like total-size, but use map instead of calling prefix-all. ; (define (total-size-v2 p) (cond [(link-exists? p) 0] [(file-exists? p) (file-size p)] [(directory-exists? p) (foldl (lambda (f rr) (+ (total-size-v2 f) rr)) 0 (map (lambda (f) (build-path p f)) (directory-list p)))])) ;;;;;;;;;;;;;;;;;;;;;;;;; ls, Version 1: follows the template exactly ;;;;;;;;;;;;;; ; ls : (-> pathname string) ; Given a path p, return a string listing it (and all files beneath it, if a dir). ; (Perhaps 'ls-r' would be a better name.) ; (define (ls p) (cond [(link-exists? p) (string-append (path->string p) "\n")] [(file-exists? p) (string-append (path->string p) "\n")] [(directory-exists? p) (ls* (prefix-all p (directory-list p)))])) ; ls* : (-> (list-of pathname) string) ; Given a list of paths, return a string appending the 'ls' of each of them. ; (define (ls* lops) (cond [(empty? lops) ""] [(cons? lops) (string-append (ls (first lops)) (ls* (rest lops)))]))