The previous example also showed the use of binary copying of a file - it did not assume that the file contained line by line characters. It repetitively read a large number of bytes and wrote those bytes to the second file.
It is possible to have a file of any data type.
General files are binary files: i.e. data is not stored in
human readable form.
FileOutputStream out_stream= new FileOutputStream("fred.dat"); // Get a FileOutputStream object
FileInputStream in_stream = new FileInputStream("freda.dat"); // Get a FileInputStream object
FileOutputStream out_stream= new FileOutputStream("fred.dat"); // Get a FileOutputStream object
DataOutputStream data_out_stream= new DataOutputStream(out_stream); // Get a DataOutputStream object
FileInputStream in_stream = new FileInputStream("freda.dat"); // Get a FileInputStream object
DataInputStream data_in_stream = new DataInputStream(in_stream); // Get a DataInputStream object
DataInputStream
read(byte[])
Reads data into an array of bytes.
read(byte[], int, int)
Reads data into an array of bytes.
readBoolean()
Reads a boolean.
readByte()
Reads an 8 bit byte.
readChar()
Reads a 16 bit char.
readDouble()
Reads a 64 bit double.
readFloat()
Reads a 32 bit float.
readFully(byte[])
Reads bytes, blocking until all bytes are read.
readFully(byte[], int, int)
Reads bytes, blocking until all bytes are read.
readInt()
Reads a 32 bit int.
readLine()
Reads in a line that has been
terminated by a \n, \r, \r\n or EOF.
readLong()
Reads a 64 bit long.
readShort()
Reads a 16 bit short.
readUTF()
Reads a UTF format String.
readUTF(DataInput)
Reads a UTF format String from
the given input stream.
readUnsignedByte()
Reads an unsigned 8 bit byte.
readUnsignedShort()
Reads 16 bit short.
skipBytes(int)
Skips bytes, blocks until all bytes are skipped.
DataOutputStream
flush()
Flushes the stream.
size()
Returns the number of bytes written.
write(int)
Writes a byte.
write(byte[], int, int)
Writes a sub array of bytes.
writeBoolean(boolean)
Writes a boolean.
writeByte(int)
Writes an 8 bit byte.
writeBytes(String)
Writes a String as a sequence of bytes.
writeChar(int)
Writes a 16 bit char.
writeChars(String)
Writes a String as a sequence of chars.
writeDouble(double)
Writes a 64 bit double.
writeFloat(float)
Writes a 32 bit float.
writeInt(int)
Writes a 32 bit int.
writeLong(long)
Writes a 64 bit long.
writeShort(int)
Writes a 16 bit short.
writeUTF(String)
Writes a String in UTF format.
Java has the facility to use Random Access files - a record may be read from or written to any place in the file without having had to access the preceding records. Typically, a seek routine is used to position the file pointer at the right place for a subsequent read or write.
The RandomAccessFile class has the following constructors:
public RandomAccessFile(String name,
String mode) throws IOException
Creates a RandomAccessFile with the specified system dependent file name and the
specified mode. Mode "r" is for read-only and mode "rw" is for read+write.
Parameters:
name - the system dependent file name
mode - the access mode
Throws: IOException
If an I/O error has occurred.
public RandomAccessFile(File file,
String mode) throws IOException
Creates a RandomAccessFile from a specified File object and mode ("r" or "rw").
Parameters:
file - the file object
mode - the access mode
public long getFilePointer() throws IOException
Returns the current location of the file pointer.
public void seek(long pos) throws IOException
Sets the file pointer to the specified absolute position.
Parameters:
pos - the absolute position
How would we store records in a file using Java? We would
like to be able to write out the entire record into a file and
also to be able to read the entire record back. We could use:
import local.units.sdsu.io.*;
import java.lang.*;
import java.io.*;
class Record
{
public int studentNumber;
public String firstName;
public String lastName;
public double examMark;
}
public class RecordTest
{
public static void main(String argv[]) throws IOException
{
Record fred = new Record();
RandomAccessFile file = new RandomAccessFile("freda.dat","rw");
byte firstName[] ;
byte lastName[] ;
fred.studentNumber = 730372;
fred.firstName = "Andrew";
fred.lastName = "Marriott";
fred.examMark = 27.3;
file.writeInt(fred.studentNumber);
firstName = new byte[fred.firstName.length()];
fred.firstName.getBytes( 0, fred.firstName.length(),firstName,0);
file.write(firstName);
lastName = new byte[fred.lastName.length()];
fred.lastName.getBytes( 0, fred.lastName.length(),lastName,0);
file.write(lastName);
file.writeDouble(fred.examMark);
file.close();
}
}
firstName = new byte[80];
fred.firstName.getBytes( 0, fred.firstName.length(),firstName,0);
file.write(firstName);
// Write out 80 bytes each time - what is the padding?
fred.studentNumber = file.readInt();
byte firstname[] = new byte[80];
file.readFully( firstname );
fred.firstName = new String( firstname, 0 );
byte lastname[] = new byte[80];
file.readFully( lastname );
fred.lastName = new String( lastname, 0 );
fred.examMark = file.readDouble();
public int size() // Size of a Record.
{
return (
4 + // size of an integer in bytes
stringSize + // size of firstname
stringSize + // size of lastname
8 // size of a double in bytes.
);
}
import local.units.sdsu.io.*;
import java.lang.*;
import java.io.*;
public class Client
{
// Mainline Variable Declarations
static PrintStream output = System.out;
static ASCIIInputStream input = new ASCIIInputStream(System.in);
protected int studentNumber;
protected String firstName;
protected String lastName;
protected double examMark;
private static final int stringSize = 80;
private static RandomAccessFile raf = null;
private static final String NO_FILENAME_SET = "No Filename Set!";
public static void openClientFile(String name)
throws IOException
{
raf = new RandomAccessFile(name,"r");
}
public static void openClientFile(File file)
throws IOException
{
raf = new RandomAccessFile(file,"r");
}
public static void createClientFile(File file)
throws IOException
{
raf = new RandomAccessFile(file,"rw");
}
public static void createClientFile(String name)
throws IOException
{
raf = new RandomAccessFile(name,"rw");
}
public static void close()
throws IOException
{
if(raf != null)
raf.close();
raf = null;
}
public static long getFilePointer()
throws IOException
{
if(raf != null)
return raf.getFilePointer();
throw new IOException(NO_FILENAME_SET);
}
public static long length()
throws IOException
{
if(raf != null)
return raf.length();
throw new IOException(NO_FILENAME_SET);
}
public static void seek(long pos)
throws IOException
{
if(raf != null)
raf.seek(pos);
throw new IOException(NO_FILENAME_SET);
}
public String toString()
{
return(studentNumber + ":" + firstName +
" " + lastName + ":" + examMark + ":");
}
public Client( int studentnumber,
String firstname,
String lastname,
double exammark)
{
studentNumber = studentnumber;
firstName = firstname;
lastName = lastname;
examMark = exammark;
}
// Read a Client record from the specified RandomAccessFile
public void getClient() throws IOException
{
if(raf == null)
throw new IOException(NO_FILENAME_SET);
studentNumber = raf.readInt();
byte fn[] = new byte[stringSize];
raf.readFully(fn);
firstName = new String(fn,0);
byte ln[] = new byte[stringSize];
raf.readFully(ln);
lastName = new String(ln,0);
examMark = raf.readDouble();
}
// Write a record to the specified RandomAccessFile
public void putClient() throws IOException
{
if(raf == null)
throw new IOException(NO_FILENAME_SET);
raf.writeInt( studentNumber );
byte fn[] = new byte[stringSize];
if (firstName != null )
firstName.getBytes(0,firstName.length(),fn,0);
raf.write(fn);
byte ln[] = new byte[stringSize];
if ( lastName != null )
lastName.getBytes(0,lastName.length(),ln,0);
raf.write(ln);
raf.writeDouble( examMark );
}
// Size of a Record.
public int size()
{
return (
4 + // size of an integer in bytes
stringSize + // size of firstname
stringSize + // size of lastname
8 // size of a double in bytes.
);
}
public static void main(String argv[]) throws IOException
{
Client client = new Client(730372,"Andrew","Marriott",27.3);
client.createClientFile("fred3.dat");
client.putClient();
Format.print(output, client + "0);
client.close();
}
}
|
Note that many of the methods simply call the appropriate RandomAccessFile methods.
Another class which calculates the record size dynamically
and reads/writes the data in that size chunks can be designed and
the differences between our first attempt and this one are shown
below. This class uses the ByteArrayInputStream and
ByteArrayOutputStream classes.
public class Client2
{
:
private static final int stringSize = 80;
private static int recordSize = -1;
private static DataInputStream din = null;
private static ByteArrayInputStream bais = null;
private static DataOutputStream dout = null;
private static ByteArrayOutputStream baos = null;
:
// Read a Client record from the specified RandomAccessFile
public void getClient() throws IOException
{
if(raf == null)
throw new IOException(NO_FILENAME_SET);
byte record[] = new byte[size()];
raf.readFully(record,0,recordSize);
bais = new ByteArrayInputStream(record);
din = new DataInputStream(bais);
studentNumber = din.readInt();
byte fn[] = new byte[stringSize];
din.readFully(fn);
firstName = new String(fn,0);
byte ln[] = new byte[stringSize];
din.readFully(ln);
lastName = new String(ln,0);
examMark = din.readDouble();
}
// Write a record to the specified RandomAccessFile
public void putClient() throws IOException
{
putClientIntoBAOS();
raf.write(baos.toByteArray());
baos.reset();
}
public void putClientIntoBAOS()
throws IOException
{
if(raf == null)
throw new IOException(NO_FILENAME_SET);
if ( baos == null)
{
baos = new ByteArrayOutputStream();
dout = new DataOutputStream(baos);
}
dout.writeInt( studentNumber );
byte fn[] = new byte[stringSize];
if (firstName != null )
firstName.getBytes(0,firstName.length(),fn,0);
dout.write(fn);
byte ln[] = new byte[stringSize];
if ( lastName != null )
lastName.getBytes(0,lastName.length(),ln,0);
dout.write(ln);
dout.writeDouble( examMark );
recordSize = baos.size();
}
// Size of a Record.
public int size()
{
if(recordSize == -1)
{
try
putClientIntoBAOS();
catch (IOException e)
{
recordSize = 0;
}
baos.reset();
}
return (recordSize);
}
:
}
|
So we can use files for storing large (or small) temporary results just like an array (although in some languages, we can only access it sequentially). This is often useful when we have a large piece of text or data that would not fit into memory at once, that we need to process a few times. e.g. text editor, compiler, assembler, etc.
import local.units.sdsu.io.*;
import java.lang.*;
import java.io.*;
class Client;
{
// Data of the client record.
// Methods to read and write the client data.
}
public class MatchMaker
{
// Mainline Variable Declarations
static PrintStream output = System.out;
static ASCIIInputStream input = new ASCIIInputStream(System.in);
static Client match, applicant ;
static int count;
public static void main(String argv[]) throws IOException
{
: // Get information about applicant
count = 0;
match.openClientFile("clientel.dat");
applicant.createClientFile("possibles.dat");
while ( !match.eof() )
{
/* get a client from file to match against applicant */
match.getClient();
if( (applicant.sex != match.sex) &&
(applicant.age - match.age<=5) &&
( )
( )
{
count++;
applicant.putClient();
}
}
if (count==0) Format.print("Better became a nun or monk");
else
{
applicant.close();
applicant.openClientFile("possibles.dat");
while ( !applicant.eof() )
{
applicant.getClient();
/* printout vital information */
}
}
}
}