Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

A Simple Filesystem and Shell While the binary trees we've seen in class have parent-child relationships, there isn't much meaning to this hierarchy. These relationships

A Simple Filesystem and Shell

While the binary trees we've seen in class have parent-child relationships, there isn't much meaning to this hierarchy. These relationships simply capture the order in which data was inserted, but are not really important to the programmer using our trees.

In other applications, these parent-child relationships actually store useful information. One such example was our expression trees from the previous assignment. There, the structure of the tree stored the order of the operations.

Another example is in file systems. Here, a parent-child relationship represents enclosure. Parent nodes are directories, and all of their children are members of that directory.

In this assignment, you will create a simple file system and a simple text interface allowing a user to interact with that file system. (This is often referred to as a shell or a command-line interface (Links to an external site.)Links to an external site.; think Command Prompt on Windows, or Terminal on a Mac.)

What to Do

Open Eclipse and create a new Java project.

In this project, you'll be implementing three classes. The file system will consist of two classes: FileSystem and FileSystemNode, described in Part I, below. The user interface (shell) will be implemented in a single class, Driver, described in Part II, below.

After reading through these parts, see Sample Output and Hints for further information.

Part I: The File System

Our file system will be represented with two classes: FileSystem and FileSystemNode. These two classes are like our tree class and tree node class, respectively.

A FileSystemNode object represents either a directory or a file. It should store the following member variables:

A String containing the name.

A boolean determining whether the node is a directory or a file.

A List of children (since a directory may have many children).

A FileSystemNode reference to its parent (this will be null if the node is the root).

A FileSystem object stores the entire file system and the user's current location in it (called the "current working directory"). It should contain the following member variables:

A FileSystemNode representing the root.

A FileSystemNode reference representing the user's current working directory.

When you construct an empty file system, the root is not null. It should be a directory with no name (called the root directory of a file system).

You must implement the following methods, which allow the user to interact with your file system. Most of these methods correspond to common UNIX shell commands:

public void cd(String dir_name)

Short for "change directory", this method changes the current working directory.

It should search the current working directory for a FileSystemNode named dir_name, and set the current working directory to that node.

If no such entry exists, or if that entry is not a directory, print an error message.

There are also two special entries:

if dir_name is a single period ("."), then do nothing. In most shells, this is a special name that means "the current directory".

if dir_name is two periods (".."), then change to the parent directory. In most shells, this is a special name that means "the parent directory".

public void ls()

Short for "list", this method prints out the children of the current working directory.

It should iterate through the children of the current working directory and print out their names. It should also print a prefix for each entry, indicating whether it is a file or a directory. For files, print "(f)" before the name. For directories, print "(d)" before the name.

public void mkdir(String dir_name)

Short for "make directory", this method creates a new, empty directory with the given name and adds it to the current working directory.

If there is already a child with this name (either a file or a directory), then just print out an error message.

public void pwd()

Short for "print working directory", this method prints the full path of the current working directory.

The "full path" is simply the names of all ancestor directories in order, separated by slashes. For example, if the current working directory is a folder named "music", which is inside a folder named "home", which is inside of the root directory, then the full path is "/home/music/".

public void rm(String file_name)

Short for "remove", this method removes a file of the given name from the current working directory.

It should search the children of the current directory for a file with the given name, and remove it. This method should only work on files.

If the entry doesn't exist, or if it is a directory, print an error message and do nothing.

public void rmdir(String dir_name)

Short for "remove directory", this method removes a directory of the given name from the current working directory.

It should search the children of the current directory for a directory with this name, and remove it. This method should only work on empty directories.

If the entry doesn't exist, if it is a file, or if it is a directory with children, print an error message and do nothing.

public void touch(String file_name)

This method simply creates a file of the given name in the current working directory.

If there is already a child with this name (either a file or a directory), then just print out an error message.

public void tree()

This method prints a pre-order traversal of the files in the subtree rooted at the current working directory. See Sample Output for an example.

Part II: The User Interface

In the Driver class, there should be a main method which does the following:

Creates an empty file system.

Loops forever, accepting user inputs from the keyboard.

The user should be able to enter the following commands, most of which simply call that function on the FileSystem object. Note: in each of these commands, stuff in angle brackets indicate a user supplied parameter. For example, "cd " means the user typed "cd", then a space, followed by a directory name.

cd :: calls FileSystem.cd() with as an argument.

exit :: immediately exits the program.

ls :: calls FileSystem.ls().

mkdir :: calls FileSystem.mkdir() with as an argument.

pwd :: calls FileSystem.pwd().

rm :: calls FileSystem.rm() with as an argument.

rmdir :: calls FileSystem.rmdir() with as an argument.

touch :: calls FileSystem.touch() with as an argument.

tree :: calls FileSystem.tree()

Sample Output

Here is a sample run of a shell. It starts with an empty file system and adds several items. Note that the "> " is just prompting the user for a command; it's printed out by the program and not typed by the user:

> ls > touch file > mkdir music > ls (f) file (d) music > cd music > ls > touch song1.mp3 > touch song2.mp3 > ls (f) song1.mp3 (f) song2.mp3 > cd .. > ls (f) file (d) music > tree ./file ./music/ ./music/song1.mp3 ./music/song2.mp3 > cd music > pwd /music/ > tree ./song1.mp3 ./song2.mp3 > exit Goodbye!

Below is another example, which demonstrates removing files after they have been created:

> touch file > mkdir dir > cd dir > touch file > cd .. > ls (f) file (d) dir > rmdir file error: "file" is not a directory > rm dir error: "dir" is not a file > rmdir dir error: can only remove empty directories > rm file > ls (d) dir > cd dir > ls (f) file > rm file > cd .. > rmdir dir > ls > exit Goodbye!

Hints

I'd suggest the following order of implementation; it allows you to start with a fairly basic set of features and then add things incrementally:

First, implement the FileSystem class with only method stubs. Method stubs simply declare all of the methods, but don't really implement them (they often just contain a print statement like "TODO: implement this later").

Next, using these method stubs, implement the Driver class. This class is fairly simple, and having it done will allow you to immediately test methods as you implement them.

Next, implement ls(), and then touch() and mkdir(). These get you some basic functionality adding nodes.

Next, implement cd() and pwd(). These add navigation to your shell.

Next, implement rm() and rmdir(). These allow you to remove items you've created.

Last, implement tree(). This one is the trickiest, as it requires recursion to do correctly.

Some other general hints:

For the FileSystemNode class, try adding helper methods, like we did for TreeNode in class, to make your code more readable.

Try to use the Java classes for Lists and their Iterators. Reuse as much of their code as you can, since it is reliable and makes your life easier!

We didn't mention it much in class, but some Iterators have a method remove() (Links to an external site.)Links to an external site., which is really useful for our rm() and rmdir() methods.

What to Submit

When you are finished, submit a zip of your project on Canvas. This should, at least, include:

Driver.java

FileSystem.java

FileSystemNode.java

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

IBM Db2 11 1 Certification Guide Explore Techniques To Master Database Programming And Administration Tasks In IBM Db2

Authors: Mohankumar Saraswatipura ,Robert Collins

1st Edition

1788626915, 978-1788626910

More Books

Students also viewed these Databases questions

Question

I am paid fairly for the work I do.

Answered: 1 week ago

Question

I receive the training I need to do my job well.

Answered: 1 week ago