Question: write a terminal program We'll implement the following shell operations cd --change directory. Move to the new directory. The special directory .. is the parent
write a terminal program
We'll implement the following shell operations
cd --change directory. Move to the new directory. The special directory .. is the parent directory of whatever folder you're in
ls -- list. Lists all the files and folders in the current directory
touch -- make a new empty file with the given name
mkdir -- make a new empty directory with the given name
pwd -- "present working directory" print the path to the current directory, starting with the root.
rm -- remove a file. It's an error to use this on a directory
rmdir -- remove an EMPTY directory. It's an error to use this on a file or a directory with stuff in it
tree -- pretty-print the contents of this directory recursively using a pre-order traversal with currentDirectory as the root. Each level down will have tabs in front of it. More on that below
We'll be writing two classes: Filesystem, and Driver. The Filesystem class will contain the information about the folders/files we have and have methods for the various commands. The driver will read user input from the keyboard and call the appropriate methods as well as take care of some file IO stuff.
As you can imagine, we'll be representing our filesystem using a tree structure. In particular, we'll be using a linked tree with the following node inner class type inside the Filesystem class:
Node:
It should implement Serializable. Remember this requires no extra methods to be defined
member variables: String name, ArrayList of children nodes (will be null if this isn't a directory), Node parent
Constructor(String name, Node parent, Boolean isDirectory) --make a new node. Specify whether it's a file or a directory
isDirectory() -- return true if this node is a directory, false if it's a regular file
children() -- return the arrayList of children nodes. Since we won't be using nodes outside of our filesystem class this privacy leak is tolerable.
appendChild(name, isDirectory) -- add a new child to this node
isRoot() -- return true if this node is the root (it's parent is null)
Also in the Filesystem class:
It should implement Serializable. Remember this requires no extra methods to be defined
Node root, Node currentDirectory
Constructor: make a root node with the name "" and set current directory to root
checkMakeFile(name). If the current directory has a child with name already, throw an exception. Otherwise do nothing
ls() --print all the children of the current directory
mkdir(name). Add a new directory child node to the current directory. Throw an exception if the name already exists
touch(name). Same, as mkdir, but make a new file, not a directory
pwd() --print the full path name of the current directory starting with root. Separate them by slashes. You should get something like /path/to/currentDirectory/ as output. More on this below.
cd(name) change the currentDirectory to name. If the currentDirectory doesn't have a child named "name" that is a directory, throw an excecption
rm(name) remove the file "name" from the currentDirectory. Throw an exception if it's a directory or does not exist.
rmdir(name) remove the directory "name" from the currentDirectory. Throw an exception if it's not a directory, or if it's not empty
tree() pretty print the tree rooted at currentDirectory. Use a preorder traversal with a helper function like we did in class. The helper function should takes an extra int parameter that says how many tabs to print in front of everything. When you make a recursive call, you should print one more tab than you were before.
pwd will work by walking up to the root, so the string you need to output will be built up backwards. We saw that using += is slow for strings, because each time you do that it creates a brand new string. Make this method efficient by doing the following:
add each string to a stack
create a StringBuilder object and append the entries in the stack to the StringBuilder. Recall we saw how to use a stack to reverse a list... that's what we're doing here.
Print the stringBuilder using its toStringMethod
The second class is the Driver. It should have a main where you should:
create a Filesystem object. You should try to read it from a file called "fs.data" using an ObjectInputStream. If you can't, use the constructor that creates an empty Filesystem.
Create a scanner and connect it to System.in
Until the user types quit, listen for the commands above and call the appropriate methods of your filesystem method. Catch any exceptions that arise so the program doesn't crash
Once you exit your main loop, save the filesystem using ObjectOutputStream to the file "fs.data"
When you finish, submit your zipped project to Canvas
Here is a sample session (I print $ before I listen for user input):
$pwd
/folder/
$cd ..
$ls
folder
file
$cd file
couldn't change directory: no such directory
$ls
folder
file
$cd ..
$pwd
/
$
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
