Persistent data is stored in files, which are stored on hard disks, flash drives, etc. This website discusses the following ways to access a file:
A file itself is just a bunch of related records, companies payroll, stocks, etc. Files themselves can grow to a very large size normally determined by the operating system. There are many ways of organizing records in a file, the common type is called sequential file in which records are typically stored in order by the record-key field. In some instanaces records could be stored in a database but even a database stores its data in files.
File and Streams
Java views each file as a sequential stream of bytes, each file ends with either an end-of-file marker or at a specific byte number record. Three streams are automatically created when we begin executing a Java program
The java.io package contains many classes and interfaces that relate to Java I/O a portion of it is below, they can be categorized in the following
Byte Stream Classes | ||||
File | An abstract representation of file and directory pathnames | |||
FileDescriptor | Serves as an opaque handle to the underlying machine-specific structure representing an open file, open socket or another source or sink of bytes. | |||
InputStream | This abstract class is the superclass of all classes representing an input stream of bytes. | |||
ByteArrayInputStream | contains an internal buffer that contains bytes that may be read from the stream | |||
FileInputStream | obtains input bytes from a file in a file system | |||
FilterInputStream | is the superclass of all filter input streams, uses its source to possibility tranform data or providing additional functionality | |||
BufferedInputStream | has the ability to buffer the input to support the mark and reset methods | |||
DataInputStream | lets an application read primitive data types from an underlying input stream in a machine-independent way. | |||
PushbackInputStream | adds functionality to another input stream namely the ability to "push back" or "unread" one byte PushbackInputStreams are used by programs like compilers that parse there inputs. |
|||
ObjectInputStream | deserializes primitive data and objects previously written using an ObjectOutputStream | |||
PipedInputStream | provides whatever data bytes are written to the piped output stream | |||
SequenceInputStream | represents the logical concatenation of other input streams, basically reads a file then moves on the next file and so on. | |||
OutputStream | This abstract class is the superclass of all classes representing an output stream of bytes. | |||
ByteArrayOutputStream | implements an output stream in which the data is written into a byte array. The buffer will grow automatically as data is written to it. | |||
FileOutputStream | an output stream for writing data to a file or a filedescriptor. | |||
FilterOutputStream | is the superclass of all filter output streams, uses its source to possibility tranform data or providing additional functionality | |||
BufferedOutputStream | an application can write bytes to the underlying output stream without causing a call to the underlying system for each byte written | |||
DataOutputStream | lets an application write primitive data types to an output stream in a machine-independent way | |||
PrintStream | has the ability to print representations of various data values conveniently. this is used for performing output to the screen (System.out, System.err) |
|||
ObjectOutputSteam | writes primitive data and objects types to an ObjectOutputStream | |||
PipedOutputStream | can connect to a piped input stream to create communications pipe | |||
RandomAccessFile | Instances of this class supports read and writing to a random access file Used for direct-access applications such as transaction-processing applications (airline-reservations, point-of-sales, etc), direct-access application provide rapid access to specific data items in large files, this means data is supplied quickly so customers do not have to wait long for an answer. |
|||
Character Stream Classes | ||||
Reader | abstract class for reading character streams | |||
BufferedReader | read text from a character input-stream, buffering characters so as to provide for the efficient reading of characters, arrays and lines. | |||
LineNumberReader | A buffered character-input stream that keeps track of line numbers | |||
CharArrayReader | this class implements a character buffer that can be used as a character-input stream | |||
FilterReader | abstract class for reading filtered character streams | |||
PushbackReader | character-stream reader that allows characters to be pushed back into the stream | |||
InputStreamReader | is a bridge from bytes streams to character streams | |||
FileReader | used for reading streams of characters | |||
PipedReader | piped character-input stream | |||
StringReader | character stream whose source is a string | |||
Writer | abstract class for writing character streams | |||
BufferedWriter | write text to a character output-stream, buffering characters so as to provide for the efficient writing of characters, arrays and lines. | |||
CharArrayWriter | this class implements a character buffer that can be used as a character-output stream | |||
FilterWriter | abstract class for writing filtered character streams | |||
OutputStreamWriter | is a bridge from character streams to byte streams | |||
FileWriter | class for writing character files | |||
PipedWriter | piped character-output streams | |||
PrintWriter | print formatted representations of objects to a text-output stream | |||
StringWriter | a character stream that collects it output in a string buffer which can then be used to construct a string |
You should use a character-oriented stream to read in console input, this allows you to accept international characters, there are a number of ways to read console input the the most popular are below
Using BufferReader | public class ConsoleReader1 { public static void main(String[] args) { String name = ""; System.out.println("Enter your name"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { name = br.readLine(); } catch (IOException e) { e.printStackTrace(); } System.out.println("Your name is: " + name); } } |
Using Scanner | public class ConsoleReader2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter your name: "); String name = scanner.nextLine(); System.out.print("Enter your age: "); int age = scanner.nextInt(); System.out.println("Your name is " + name + " and you are " + age + " year old"); } } |
Using Console (now perferred) | public class ConsoleReader3 { public static void main(String[] args) { Console console = System.console(); if (console == null) { System.out.println("No console: non-interactive mode!"); System.exit(0); } System.out.print("Enter your username: "); String username = console.readLine(); System.out.print("Enter your password: "); char[] password = console.readPassword(); String passport = console.readLine("Enter your %d (th) passport number: ", 2); System.out.println("Your name is " + username + " and your password is " + password); } } |
The below example demonstrates how to write and read from a sequential file. I am using a few features not yet discussed but its easy to write and read back from a file in Java, I do cover the File class later in this section.
Sequential File Access | public class FileIO { public static void main(String[] args) { writeFile(); readFile(); } static void writeFile() { File file = new File("testfile.txt"); String content = "This is the text content"; try (FileOutputStream fop = new FileOutputStream(file)) { \\ using the new try-resources-close // if file doesn't exists, then create it if (!file.exists()) { file.createNewFile(); } // get the content in bytes byte[] contentInBytes = content.getBytes(); fop.write(contentInBytes); fop.flush(); fop.close(); System.out.println("Done"); } catch (IOException e) { e.printStackTrace(); } } static void readFile() { File file = new File("testfile.txt"); try (FileInputStream fis = new FileInputStream(file)) { \\ using the new try-resources-close System.out.println("Total file size to read (in bytes) : "+ fis.available()); int content; while ((content = fis.read()) != -1) { // convert to char and display it System.out.print((char) content); } } catch (IOException e) { e.printStackTrace(); } } } |
Many airline reservations and point-of-sales systems use random access files, you can acess the files directly and quickly without searching through all the other records first. With random access files you need to create the structure, normally you make sure that all records are the same length but there are other techinques as well. The file structure is like a railroad train which has many carts (all the same size), some empty and some that contain contents. Data can be inserted without destroying other data, also data can be updated and deleted without having to re-create the file.
The below example demonstrates how to access a random file, the program code could be improved but i have tried to make it very simple even if it means using duplicate code. Pay attention to the code in bold this the important random-access file stuff.
Random File access | import java.io.*; // Display the offset |
The File class is useful for obtaining information about files and directories. Objects of class file do not actually open a file or provide any file-processing capabilities. The file class can provide the following and a lot more.
There are many methods in the File class, I have listed some of the more commonly used ones
canRead() | Returns true if the file is readable, false otherwise |
canWrite() | Returns true if the file is writeable, false otherwise |
delete() | Delete a file or directory |
exists() | Returns true if the file exists, false otherwise |
isFile() | Returns true if the file is a file, false otherwise |
isDirectory() | Returns true if the file is a directory, false otherwise |
isAbsolute() | Returns true if the file is the absolute path to the file, false otherwise |
getAbsolutePath() | Returns a String with the absolute path of the file or directory |
getName() | Returns a String with the name of the file or directory |
getParent() | Returns a String with the parent directory of the file or directory |
length() | Returns the length of the file in bytes (long). |
lastModified() | Returns a platform-dependent representation of the time when the file or directory was modified (long) |
list() | Returns an array String representing the contents of a directory. |
mkdir() | Creates a directory |
mkdirs() | Create a directory, including any necessary but nonexistent parent directories |
renameTo() | Rename a file or directory |
setReadOnly() | Marks a file or directory as read-only |
Examples |
|
File example | import java.io.*; import java.util.Date; public class fileTest { public static void main(String[] args) { File f = new File("d:\\java\\fileTest\\classes\\payroll.doc"); File test1 = new File("d:\\java\\fileTest\\classes\\test1.doc"); File test2 = new File("d:\\java\\fileTest\\classes\\test2.doc"); File dir1 = new File("d:\\java\\fileTest\\classes\\payroll\\employee"); File dir2 = new File("d:\\java\\fileTest\\classes\\payroll\\employee\\HR"); File dir3 = new File("d:\\java\\fileTest\\classes\\payroll\\employee\\Sales"); try { System.out.println("Read the file:" + f.canRead()); |