Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Programming Project
Attached Files
A prototype for a Stateless
File Server and its Cache
Mechanisms
by Kohei Honda kohei@dcs.qmw.ac.uk
Introduction
This project concerns the design and implementation of a
simple stateless file server and its client-side API. It will
give you experience in the use of TCP for communication
between client and server and in the design of a client-side
cache. Your system will tested with a weather forecast
database which is potentially very large.
The specification of the coursework is to found here.
The interface of the client-side API (which you should
implement) is provided below, together with a default
client and a data file with which you can test your software.
Java Files for Coursework
Basic APIs
The Java interface for the client API for the file system is
given in the file fileSystemAPI.java and the subsidiary
definition of the class filehandle is given in the file
filehandle.java. The program in the file checkfh.java can be
used to check whether the filehandle class works correctly.
The client program in testClient.java is for testing the
communication between your client API and the file server.
The program arguments specify the IP address and port of
the server and the file name. The program repeatedly calls
the read operation in the client API to get the weather
forecast data from the file server. It includes timing
statements allowing you to measure the performance of
your client-server interaction.
Test Data
A small sample of weather forecast data is supplied in the
file data.txt
The file fileSystem.java provides a simple example
implementation of the client API of the file system. It
provides the operations open,, read etc. on a local file.
These must be replaced by operations that communicate by
means of TCP with the file server. The file testCl.java is a
version of testClient.java that works with this simple
implementation - it supplies open with the name of a local
file (the IP address and port are not required). You can
compile and run these tests with data in a local file, for
example: java testCl data.txt.
A set of questions and answers can be found in the FAQ.
Additional Notes
1) Report
Please write a report which clearly describes the design of
your software. In particular, if your design deviates from
the specification please document this carefully. It is very
important for me to know whether the design is wellthought out or not.
Other points:
• Point out clearly in the report any good features: a good
working cache, concurrency control, error handling,
etc. These points will be considered when marking.
• I hope your codes are decently commented, but first of all
try to prepare a readable report.
• If you made efforts on design but have not been able to
make your code run, you can still submit a report
describing your design as concretely as possible.
Although I will not be able to offer high marks, this
does count.
2) Document how to run your code
You should document how your software can be run. In
particular, note the following points. In testing, the test for
reading is emphasized since this is mainly about caching.
Separately I will also check the writing function.
(a) You will use TCP, then I need to run a server-side file
system, and we need to compile a client using your Clientside file system. If possible, use the name
fileSystem.java
(which implements, as default, fileSystemAPI) for your
client-side FS. If you hard-wire IP, directory etc., that is
OK but write a note on this.
3) Generally on Design.
There are quite a few questions about design decisions, for
example about how a client-side write should work w.r.t.
caching. As I wrote in the specification, write-through (as
written in the textbook) is one way, but alternatively, you
can write to cache and then "flush" later. Other options
exist. Any reasonable design is fine, but document well
what your system does.
!supportLineBreakNewLine]
[endif]
Frequently Asked Questions
1. General
1.1. What is this project about, in general? What is its
context?
Suppose you want to create an application which reads and
writes files over the Internet. The remote file system is in a
certain host, while your application resides in a local host,
separated by a network. Your goal is to make it possible for
your local application to be able to read and write data in a
file system at a remote site.
1.2. What basic components are to be made? What are
their requirements in brief?
Assuming the network runs TCP/IP (which is usually the
case) and using Java, you can achieve your goal by making
the following components:
[if !supportLists]1. [endif]A server-side file system (which
directly reads and writes data to files, based on commands
sent over the network). This component can use standard
Java APIs for file operations and for network
communication, and, once run, will always be listening to a
request at a certain port on the host in which it is running.
[if !supportLists]2. [endif]A client-side file system (which
accepts requests from a client, translates them into
commands sent over a network to (1), receives data and
returns it to the client. This part may also involve a caching
mechanism. This is realized as an API which YOU
implement as a Java class which is imported by a client in
order to use the file server.
The main thrust of the coursework is for you to realize
these two components so that they can offer basic file
operations over the internet, however far away a remote file
resides.
We ask for (1) to be STATELESS, and (2) to offer a
specified API. In stage 2, (2) should incorporate cache
mechanisms. For details, see the spec.
1.3. Should we implement concurrency control, readwrite locks, etc.?
These are excluded from the requirements, to avoid giving
you too much work. In general, adding these mechanisms
soundly could result in additional marks. However not
having them does not result in any deduction in marks.
1.4. What are the best references to read for
understanding what to make?
The textbook CDK3 and my specification. For caching
mechanisms, the textbook has detailed coverage (NFS and
Andrew are the two best references).
1.5. In the specification, Stage 2 is divided into two
phases. Why so?
Stage 2 is about making a cache mechanism. In case you
are short of time but you wish to have a clear achievement,
I divided this into (A) caching without a cache coherence
mechanism (updates may not be reflected) and (B) caching
with consistency (updates would be reflected, either by the
client-side using last modified time/staleness, or by the
server-side using call-backs (or other means if you think
appropriate). If you only implement (A), then you should
also present the design for (B) on the basis of your
implementation.
If (A) and (B) are working perfectly with sound design and
documentation, then that is the best. The next is only (A)
with sound and clear design. Then third best is to do a
sound and implementable design for (A) and (B). In the last
case, you should really be concrete about the design, or you
may not get substantial marks.
2. File Paths and File Handles.
2.1. Are there two kinds of file handles: on the serverside and the client-side?
Yes, in general. On the server side, file handles identify
individual files. On the client side, file handles (which
clients use) are used for each client to issue their operations
without specifying file names. A server can return its own
file handle to a client, but this is not in general necessary
since a socket identifies a file with which the client-side file
system interacts with the server-side. Returning server file
handles is not recommended because it is not secure!
I specified the internal structure of file handles on the
client-side (see filehandle.java). This can be changed
provided that the same interface is offered to client
programs.
2.2. Should a directory file service be provided at the
server-side?
No, this is not necessary. Implementing this is not so
difficult, and it is good practice, so there could be
additional marks for such functionality. In general, I
recommend you to concentrate on the main, required,
functionalities.
3. Write Operations.
3.1. Should the write be write-through?
If a server-side file system is issued a write, this should be
write-through by default (as you learned). For the clientside, this can vary. The simplest idea is to make it always
write-through, both at the client and the server side. When
you incorporate caching, you can also write on the cache,
and use "flush" method (which you can additionally
implement) to do the real writing. Whichever design you
choose, specify clearly in the documentation.
3.2. How does a pointer move when writing?
It simply moves to the next byte of what you wrote.
3.3. Can a client do the read and write to the same file
hanlde?
Yes, especially in the first stage. This would be different
from commonly used file interfaces. A good reference for
the standard file interface in Java is the Java 2 class
FileOutputStream.
You can make your interface only for writing and only for
reading, by specifying it when you open a file. This is not
necessary, especially for Stage 1. However this design
option is also permitted.
4. Read Operations.
4.1. When there is a cache, how is read done?
There is no change in the server-side operation. For a client
side, as you already learned, it reads from a cache if there is
data there and it is not stale.
As I noted in the specification, you can cache the whole file
in the client, or only part of it, according to your design
choice.
4.2. How does a pointer move when reading?
It simply moves as a client reads on, in the same way as in
the standard Java file read.
4.3. Need any server operations be stateful?
Not necessarily, but if you use call-backs for cache
coherence, yes. It depends on your design choice. Note
server-side operations (which your client-side file system
would use) can be changed, according to your needs. For
example, I require them to be stateless (which is one of the
aims of this project), but if you have really a very good
argument then you would add/replace with stateful
operations. In general, however, it is safer to use the
stateless operations.
5. Variations, Marking. etc.
5.1. Should I definitely use the default client?
You can use your own client and data, including
measurement, but you should implement the same (or
almost the same) API for a client as specified in
FileSystemAPI. If you deviate from the specification, you
should give arguments for your choice.
The bottom line is that your API should work with any
client which uses it, with any data provided.
In the final testing, I will add more lines to the data, so that
checking takes substantial time.
5.2. Can we share ideas/code with others?
For the main part of the software, you should make your
own efforts. However discussions among friends are not
dissuaded at all: acknowledge such discussions. Further, if
you do use another's class, you can acknowledge it. If your
design is original and you use only a small part and
acknowledge it, then it is fine.
Another possibility for code sharing is when you really
wish to implement a challenging design. For example, if
you want to make a fully functional Internet file system
incorporating concurrency control, caching, locking etc.,
you can share your work and acknowledge which part one
did. This is risky in terms of marking since, if this does not
go well, I may not be able to give good mark at all.
However if you and your friend are quite confident with
each other's skills, this would be an option. In this case I
restrict the number to two: make it clear about individual
contributions, and you should contact me before embarking
on this.
5.3 In the end how will marking be done?
I already wrote about this in the specification. I here add:
the total does not exceed 20 marks, it is always better to
have running code, documentation is considered (make it
clear about your design choice).
6. Miscellaneous
6.1. Why does the current test client read data bytebyte-byte?
Simply I did not have much time. It would be better if it
read data line-by-line. Change this as you like! 6.2. The read for the Client-side API and the one
in fileSystemAPI differ. Why?
The read in the client-side API is stateful - it just reads a
given number of bytes from the current file pointer. The
read in the fileSystemAPI is stateless - it reads a given
number of bytes from a given offset in the file.
1. Basic Description of Coursework
Background. This coursework is about the design of the
system components required to support an application
which reads and writes a file over the Internet.
Objectives. Your task is to make a pair of components: a
file server (to be remotely situated) and a client-side
library. Clients can use these two components to access a
file located remotely, by means of TCP over the Internet.
The objective in carrying it out is to obtain a deeper
understanding of stateless file servers and their cache
mechanisms. You are asked to produce two pieces of
software:
(1) A simple stateless file server, which reads from files
and writes to files in response to requests transmitted over
TCP. It provides simple read, write and get-attribute
operations. You do not need to provide other mechanisms
such as security, locking, concurrency control and fault
tolerance.
(2) A library class (API) for a client of (1), enabling it to
interact with (1) over the Internet. This part is to be done in
two stages: no caching is required in the first stage; in the
second stage you should incorporate it. (You can also make
a client itself, although a default client is provided.)
You are not required to implement a file server's most
complicated bits, i.e. the direct interface with a disk device
driver. Your server simply uses Java's standard API to
open, read, write and close files. This is because the
objective of this coursework is to create a stateless file
server which allows clients to access files via TCP requests,
and to learn about cache mechanisms on the client side.
Your system will be tested by using a specific application a weather forecast database. A client requests data by
sending a request over the Internet specifying a file name,
the data is read by a remote server, which sends it as a reply
to be displayed by the client. The default data and clients
for checking the functionalities and measuring the
performance are provided.
Stages. There are two stages in this coursework. The first
stage is to design and implement a file server and a its
client-side API without a cache mechanism. The second
stage is to design and implement a cache mechanism which
may use what NFS usually does (easier), or may be based
on call-backs (more difficult). The second stage is Optional
– Extra Credit.
2. Detailed Specification
2.1 Remote file server
File Path. The server has a ``default directory'' (which
should be one of the subdirectories of your home). A user is
supposed to initially specify the file name in the following
form: IP-address:port/filepath'. The IP-address refers to
the host where your server is running: for example it can be
Bronwyn (one can use a URL instead of an IP-address).
Port is the port at which your server is listening, which can
be any 16 bit number greater than 1023. For security
reasons, only allow the filepath to include a single file
name without a directory path, i.e. check that the file name
does not contain ``/''. This is important since, in this way,
any possible disaster in your home directory is restricted to
that specific directory.
Operations. Apart from the initial lookup operation,
operations are done via a file handle (which is a long
integer by default). The server will export only read, write
and getattribute operations. Concretely the interface which
the server will export to your client-side library should be:
• res = read(fh, offset, n), where res contains (1) a
sequence of bytes read (if the end of the file is
encountered, up to there) and (2) the last modified
time of the file.
• res = write(fh, offset, data), where res contains (1) a
boolean which tells the result of operation, and (2) the
last modified time of the file. The default semantics is
write-through.
• res = lookup(IP:port/path), where res contains (1) the
file handle and (2) the last modified time.
• res = getattrib(fh), where res contains the last modified
time of the file.
Note these are not Java methods: they are protocols
exchanged between your server and your client-side library.
So you can fill its details as you prefer as far as operations
are stateless.
Statelessness. The server should be designed to be
stateless. As already noted, it is not necessary to have
multi-threading, concurrency control, etc. for this. As far as
this requirement is satisfied, any reasonable design is
permitted, even though the more you deviate from the
above the more clearly you should specify the justification
of your design in your document. The design of the server
may not differ between the two stages, except that new
operations may be added (such as those for callbacks, or for
specifying the mode with which a file is being used).
2.2 Client-side API
2.2.1 Stage 1
Operations. The realisation of a client-side API which
interacts with a stateless server is the main topic of this
project. You should provide (a simplified version of) the
standard stream-based operations which you are familiar
with. While certain variations are allowed, it is required
that you realize the following interface.
• fh = open(IP:port/path), where fh is a file handle. This
may or may not be the same as the handle used in the
remote file system.
• res = write(fh, data), where res contains a boolean which
tells the result of the operation (success or failure).
• res = read(fh, byte [] data), where the resulting data is
read to the byte array data (if the length of the array
data is n, then n bytes are read). If fh is at the end of
the file, that part is read as null.
• res = close(fh), where res contains a boolean which tells
the result of the operation.
The above API is to be realised as Java methods. The
definition of its interface is provided.
Semantics. The following gives the preferred semantics.
• File-pointer. This simply moves on as you read/write
data, starting from the beginning and finishing at the
end of the file. At the time of open, you may specify
the mode as reading or writing - this is not necessary
in Stage 1.
• Reading. This simply reads from the file.
• Writing. Writing should be write-through.
Fundamental Requirement. Your software should run,
with clear and readable documentation: in particular, any
client which uses the interface above should be able to
read/write a file remotely over the net.
2.2.2 Stage 2 (Optional – Extra Credit)
Operations. These are the same as Stage 1, though you
may add a read/write mode in the open operation for the
control of caching.
Semantics. Here you should add a client-side cache
mechanism to your original program. Thus, the
method read on the client-side will read from the cache.
The method write may still be write-through, but must also
write on local cache.
For implementation of the cache mechanism, two possible
ideas are:
• What you can find in NFS, i.e. the one based on staleness
(oldness) of the data and a timestamp.
• The eager or aggressive caching of the whole file,
together with a call-back mechanism (see the textbook
for the idea).
These two are the recommended ways, though other forms
may be possible if they make sense.
Fundamental Requirement. In general, a cache
mechanism consists of (A) storing data locally and reading
from it as far as possible, and (B) controlling the coherence
(consistency). To get a moderate mark from this stage, you
should at least complete (A) and give a design for (B)
based on your implementation.
3. Deliverables
3.1 Stage 1:
This stage should accompany runnable source codes.
• Programs:
source files compilable and runnable under
Windows.
• Document (1-3 pages):
1. Basic documentation on the specs and the design. In
addition to the flow diagrams of the applications including
the client and the server as well as the library class (API)
for a client.
2. Measurement results of read-write operations for your
server (using the default data provided).
3. Brief discussions on those functionalities which are not
included in the given specification but which are necessary
for a (local area and distant) distributed file service.
Stage 2: (Optional – Extra Credit)
This stage can be submitted in three variations. (1) A
concrete and clear design without any runnable code; (2) In
addition, the implementation of part (A) in 2.2.2; (3) In
addition, the implementation of part (B) in 2.2.2, i.e. a fully
functional cache mechanism. (2) and (3) will be marked
substantially highly than only (1). The deliverables consist
of the following.
• Program: source files compilable and runnable under
Windows.
• Document (2-3 pages):
1. Basic documentation on the specification and design of
the cache mechanism. In addition to the flow diagrams of
the applications including the client and the server as well
as the library class (API) for a client
2. Measurement results for of read-write operations for the
same task as Stage 1, this time using the cache.
3. A brief analysis of your design and the result of your
measurements, including discussions on how your cache
mechanisms (do not) contribute to the difference in
performance.
Additional Report:
Those who have completed Stage 1 and the design part of
Stage 2 can also write an essay of 1-2 pages which
discusses one of the following points:
(I) The pros and cons of call-back mechanisms in such an
application and in a wide-area file service. In particular you
would discuss the use of leases for callbacks, in the context
of various applications such as (a) this application, (b) an
application in which clients occasionally do both writes and
reads, and (c) an application whose data is updated
frequently at a server side. As another interesting point,
leases can be used for measuring the usage of a service,
hence for charging. What other ways of charging for (file)
services can you think of? What are the pros and cons of
different approaches including the use of leases?
(II) Basic security measures can be taken for a wide-area
file service. Discuss in particular (1) confidentiality and (2)
authenticity: what problems will arise and what possible
solutions can be considered.
Marking Methods
Evaluation of the submission. The submission (to be done
electronically) should consist of: (1) sources compilable
and runnable in Windows. (2) A Word file for the
document, with your Name, StudentNo, what stages you
covered, and the document itself. The structure of the
document should follow the above description (you can use
section/subsection headers etc. as appropriate).
Criteria for marking are:
• Programs:
whether they work or not; whether your design
is sound/clear/soundly-innovative or not. I take
documentation into consideration in evaluating design.
• Document: basic understanding; sound ideas; sound and
new ideas.
/* This is for a test purpose for fileSystemAPI,
using a local file system call.
*/
/* standard java classes. */
import java.io.*;
import java.util.*;
/* local file handle class. */
import filehandle;
public class fileSystem implements fileSystemAPI
{
/* It needs a table relating filehandles and real
files. */
Hashtable tbl = new Hashtable();
/* url SHOULD HAVE form IP:port/path, but here
simply a file name.*/
/* only for input. */
/* no error check whatsoever. */
public filehandle open(String url)
throws java.io.FileNotFoundException
{
FileInputStream in = new FileInputStream(new
File(url));
filehandle fh = new filehandle();
tbl.put(fh, in);
return fh;
}
/* write is not implemented. */
public boolean write(filehandle fh, byte[] data)
throws java.io.IOException
{
return true;
}
/* read bytes from the current position. returns
the number of bytes
read: if end-of-file, returns -1. */
public int read(filehandle fh, byte[] data)
throws java.io.IOException
{
FileInputStream in = (FileInputStream)
tbl.get(fh); // no error check.
int res = in.read(data);
char read = (char) data[0];
return res;
}
/* close file. you should flush the data (over the
network). */
public boolean close(filehandle fh)
throws java.io.IOException
{
((FileInputStream) tbl.get(fh)).close(); // no
error check.
tbl.remove(fh);
fh.discard();
return true;
}
/* check if it is the end-of-file. */
public boolean isEOF(filehandle fh)
throws java.io.IOException
{
byte[] dummy={0};
return (((FileInputStream)
tbl.get(fh)).available()==0);
}
}
/* standard java classes. */
import java.io.*;
import java.util.*;
/* fileSystemAPI should be implemented by your clientside file system. */
import fileSystemAPI;
import filehandle;
/* There are two methods, main and readField. The
latter does the following.
(1) It reads one field upto, but not including, a
specified delimiter.
(2) It also converts the byte array to String and
returns it.
(3) The pointer should reside after the delimeter.
It does NOT expect the file can be in a wrong
format... */
public class testClient{
public static void main(String [] args)
throws java.lang.InterruptedException,
java.io.IOException
{
// get arguments.
String IPadr=args[0]; // e.g. 223.223.223.223
String Port=args[1]; // e.g. 7777
String Filename=args[2]; // e.g. MyFile
/* Initialise the client-side file system.
The following line should be replaced by
something like:
FileSystemAPI fs=new
YourClientSideFileSystem()
in your version.
*/
fileSystemAPI fs;
// variables used.
filehandle fh;
String city, weather, date, updatetime;
long startTime, endTime;
long turnAround;
// open file.
fh=fs.open(IPadr+":"+Port+"/"+Filename);
// repeat displaying remote data and turn-around
time.
while (true){
// read the whole file, check the time needed.
startTime=Calendar.getInstance().getTime().getTime();
while (!fs.isEOF(fh)){
// read data.
city=readField(fs, fh, ';');
weather=readField(fs, fh, ';');
date=readField(fs, fh, ';');
updatetime=readField(fs, fh, '.');
// print data.
System.out.println(city+", "+weather+",
"+date+", "+updatetime);
}
endTime=Calendar.getInstance().getTime().getTime();
turnAround=endTime-startTime;
// print the turn around time.
System.out.println("");
System.out.println("This round
takes"+turnAround+"ms.");
// wait a bit.
Thread.sleep(500);
}
}
/* We need to convert between bytes and chars. we
do this by
simply getting ascii values and storing them as
bytes.
*/
static String readField(fileSystemAPI fs,
filehandle fh, char delimeter)
throws java.lang.InterruptedException,
java.io.IOException
{
/* This method reads a file byte-by-byte.
this is slow, but simple.
*/
char ch;
byte [] data = {(byte) 'a'};
int res;
String field="";
if (fs.isEOF(fh))
return null;
else {
while (true){
// reads one byte, and converts it into
character.
res=fs.read(fh, data);
if (res==-1)
return field;
else {
ch=(char) data[0];
if (ch!=delimeter) {
field=field+(new
Character(ch)).toString();
if (fs.isEOF(fh))
return field;
}
else
return field;
};
};
};
}
}
/* standard java classes. */
import java.io.*;
import java.util.*;
/* fileSystemAPI should be implemented by your clientside file system. */
import fileSystem;
import filehandle;
/* There are two methods, main and readField. The
latter does the following.
(1) It reads one field upto, but not including, a
specified delimiter.
(2) It also converts the byte array to String and
returns it.
(3) The pointer should reside after the delimeter.
It does NOT expect the file can be in a wrong
format... */
public class testCl{
public static void main(String [] args)
throws java.lang.InterruptedException,
java.io.IOException
{
// get arguments.
//
String IPadr=args[0]; // e.g. 223.223.223.223
//
String Port=args[1]; // e.g. 7777
String Filename=args[0]; // e.g. MyFile
/* Initialise the client-side file system.
The following line should be replaced by
something like:
FileSystemAPI fs=new
YourClientSideFileSystem()
in your version.
*/
fileSystemAPI fs = new fileSystem();
// variables used.
filehandle fh;
String city, weather, date, updatetime;
long startTime, endTime;
long turnAround;
// repeat displaying remote data and turn-around
time.
while (true){
// open file.
fh=fs.open(Filename);
// read the whole file, check the time needed.
startTime=Calendar.getInstance().getTime().getTime();
while (!fs.isEOF(fh)){
// read data.
city=readField(fs, fh, ';');
weather=readField(fs, fh, ';');
date=readField(fs, fh, ';');
updatetime=readField(fs, fh, '.');
// print data.
System.out.println(city+", "+weather+",
"+date+", "+updatetime);
}
endTime=Calendar.getInstance().getTime().getTime();
turnAround=endTime-startTime;
// print the turn around time.
System.out.println("");
System.out.println("This round took
"+turnAround+" ms.");
// wait a bit.
Thread.sleep(500);
}
}
/* We need to convert between bytes and chars. we
do this by
simply getting an aschii values and stores them
as bytes.
*/
static String readField(fileSystemAPI fs,
filehandle fh, char delimeter)
throws java.lang.InterruptedException,
java.io.IOException
{
/* This method reads a file byte-by-byte.
this is slow, but simple.
*/
char ch;
byte [] data = {(byte) 'a'};
int res;
String field="";
if (fs.isEOF(fh))
return null;
else {
while (true){
// reads one byte, and converts it into
character.
res=fs.read(fh, data);
if (res==-1)
return field;
else {
ch=(char) data[0];
if (ch!=delimeter) {
field=field+(new
Character(ch)).toString();
if (fs.isEOF(fh))
return field;
}
else
return field;
};
};
};
}
}
/* This is the interface to the client-side file
system. We assume
that, once you open the file, you keep a pointer,
and whenever
you write or read, that pointer moves to the next
byte. */
/* I hide the representation of the "filehandle" (given
in a separate
class file). You can change its implementation as
you like. */
import filehandle;
public interface fileSystemAPI
{
/* url has form IP:port/path. */
public abstract filehandle open(String url)
throws java.io.IOException;
/* write data starting from the current pointer. */
public abstract boolean write(filehandle fh, byte[]
data)
throws java.io.IOException;
/* read data.length bytes from the current
position; if
end-of-fike, returns -1; if not, the next byte
(position) is
returned. */
public abstract int read(filehandle fh, byte []
data)
throws java.io.IOException;
/* close file. you should flush the data (over the
network). */
public abstract boolean close(filehandle fh)
throws java.io.IOException;
/* check if it is at the end-of-file. */
public abstract boolean isEOF(filehandle fh)
throws java.io.IOException;
/* You do not have to implement the following two
methods. */
//
public abstract boolean flush(filehandle fh);
//
int n);
public abstract byte [] read(filehandle fh,
import java.io.*;
import filehandle;
public class checkfh
{
public static void main(String argv[])
{
filehandle fh1, fh2;
fh1=new filehandle();
System.out.println("one made.");
if (fh1.isAlive())
System.out.println("one is alive.");
fh2=new filehandle();
System.out.println("two made.");
if (fh2.isAlive())
System.out.println("two is alive.");
if (fh1.Equals(fh2))
System.out.println("one
this is strange..");
else
System.out.println("one
equal.");
fh1.discard();
fh2.discard();
if (fh1.Equals(fh2))
System.out.println("one
discarded and are equal.");
else
System.out.println("one
equal, this is strange.");
}
}
and two are same,
and two are not
and two are
and two are not
London; Fine; October 12; 2000; 12:30:2000.
Tokyo; Fine; October 12, 2000; 13:30:2000.
Paris; Clouded; October 12, 2000; 13:30:2000.
Beijing; Clouded; October 12, 2000; 13:30:2000.
Jacarta; Fine; October 12, 2000; 13:30:2000.
Maiami; Fine; October 12, 2000; 13:30:2000.
Berlin; Fine; October 15, 2000; 13:30:2000.
Bonn; Fine; October 15, 2000; 13:30:2000.
/* You can change implementation as you like. This is a
simple one. */
public class filehandle
{
/* The "filehandle" is simply an integer. We keep
a counter in a
static variable "cnt" so that no duplication
occurs. When
filehandle is discarded its number becomes 0. */
private int index;
private static int cnt = 1;
public filehandle()
{
index=cnt++;
}
public boolean isAlive()
{
return (this.index!=0);
}
/* checks two handles are equal or not. */
public boolean Equals(filehandle fh)
{
return (fh.index==this.index);
}
/* discarding a filehandle. you do not have to use
this. */
public void discard()
{
index=0;
}
}