• java.io.IOException: Represents I/O exceptions in general.
• java.io.EOFException extends IOException: Indicates that the end of file or stream has been reached unexpectedly.
• java.io.FileNotFoundException extends IOException: Indicates that the requested file cannot be found in the given path.
• java.lang.SecurityException extends java.lang.RuntimeException: Indicates that the requested operation cannot be executed due to security constraints.
• File operations are separated into two main groups in Java:
• File management: Opearations such as creating, renaming, deleting files and folders.
• I/O operations.
• I/O operations are not only done with files but also with different sources such as TPC sockets, web pages, console, etc. Therefore I/O operations:
• have been separated from file operations
• coded in the same way for all these different sources.
• This approach is in harmony with the nature of object oriented paradigm. However, the complexity has been increased as a side effect.
• Coded by using the java.io.File class which represents both the files and the folders in the hard drive.
• Creating a File object does not mean to create an actual file or folder.
• Creating a File object :
• Done by using the File( String fileName) constructor.
• fileName should contain both the path and the name of the file/folder.
• Full path vs. relative path.
• Using full path degrades portability
• Relativity is tricky as well: IDEs may keep source and class files in different folders.
• Path separator:
• Windows uses \ (should be denoted as \ in Strings), Unix uses /.
• What about portability?
• public static String File.separator
• public static char File.separatorChar
• File( String path, String name) and File( File path, String name ) constructors:
• Represents a file/folder with the given name in the folder given by the path parameter.
• Some methods of the class java.io.File:
• boolean exists( ); tells whether the file exists or not.
• boolean isFile( ); returns true if this File object represents a file, false otherwise, i.e. this object represents a folder.
• File getParentFile( ); Returns the directory where this file/folder resides.
• String getCanonicalPath( ) throws IOException; Returns the full path of the file/folder, including the file name.
• boolean canRead( ); Can this application read form this file?
• boolean canWrite( ); Can this application write to this file?
• boolean createNewFile( ); Actually creates the file.
• boolean mkdir( ); Actually creates the folder.
• boolean mkdirs( ); Actually creates the folder with all necessary parent folders
• boolean renameTo( File newName ); Renames the file.
• boolean delete( ); Deletes the file.
• boolean returns: True if the operation is successful.
• I/O Operations Using Streams:
• Any I/O source is represented as stream in Java
• Files, memory, command prompt, network, etc.
• Binary vs. Text format:
• Binary I/O is fast and efficient, but it is not easily readable by humans.
• Text I/O is the opposite.
• Random vs. Sequential access:
• Sequential access: All records are accessed from the beginning to the end
• Random access: A particular record can be accessed directly.
• Disk files are random access, but streams of data from a network are not.
• Java chains streams together for different working styles.
• A mechanism which allows makes it possible to write any object
to a stream and read it again later.
• This process is called serialization in the Java terminology.
• Serialization – Output operations:
• We will write entire objects to a file on disk.
• The classes of objects to be serialized should implement the
java.io.Serializable interface.
• You do not need to do anything else as the java.io.Serializable interface
does not have any methods.
• ObjectOutputStream and FileOutputStream objects are chained together
for serialization.
• Multiple objects can and should be sent to the same stream.
• About the transient keyword
• Mark a member fields of a class as transient if you do not want to
serialize it.
• You will need to do so if the class having that member has to be
serialized but you cannot mark that member’s class as Serializable.
• About the serialVersionUID member:.
• private static final long serialVersionUID = 1L;.
• We can give a particular version instead of 1, or we can have the IDE to
generate a unique identifier automatically..
• If we do not code this member, we can hide the related warning with the
@SuppressWarnings("serial") command..
• What does this member mean?.
• There will be applications which save and load objects from different
sources..
• In time, the source code of the classes of these objects may change,
as well as the source code of the aforementioned applications..
• Different versions of all those classes can exist together. In order to
avoid incompatibilities, we need a versioning mechanism..
• This mechanism is implemented by giving a different (and possibly
increasing) serial number to classes and by checking this serial in
the applications..
• Deserialization – Input operations:
• We will read entire objects form a file on disk.
• ObjectInputStream and FileInputStream objects are chained together for
deserialization.
• Typecasting is required as the objects read from a stream comes as
instances of the class Object.
• The warning “Type safety: Unchecked cast” can be suppressed by
@SuppressWarnings("unchecked")
• If these objects are to be stored in an array, we need to know how many
objects there will be.
• In the data structures that may grow dynamically, we are not faced
with this inconvenience.
• There is a method, int ObjectInputStream.available( ), but this is
somewhat buggy
• http://www.coderanch.com/t/378141/java/java/EOF-ObjectInputStream
• Moreover, readObject() doesn't return null at EOF
• http://stackoverflow.com/questions/2626163/java-fileinputstream-
objectinputstream-reaches-end-of-file-eof
• You can code a solution by letting the exception to happen, and terminate the
loop in the catch block.
• However, exception handling is not invented for altering the program
flow.
• A better alternative to writing the data object count beforehand is to use only
one container object which stores references all the data objects.
• This container object will be a data structure, such as a list or a map.
• However, the objects in the container must implement the
java.io.Serializable interface.
• If there is a relation A→B, both A and B must implement the
java.io.Serializable interface.
....
• What about working with text files or working in other modes?
• Hint: PrintWriter and InputStreamReader streams are available for text
output and input.