Unit 5 (IO Programming) 1
Unit 5 (IO Programming) 1
Unit-5
I/O programming
Text Files vs. Binary Files
A text file consists of a sequence of characters For example, the decimal integer 199 is stored as
the sequence of three characters: '1', '9', '9' in a text file Java is UTF-16, that is uses 2 bytes variable
encoding for characters '1', '9', '9' would require 6 bytes to encode it
A binary file consists of a sequence of bits For example, the decimal integer 199 is stored as one
byte binary value for the hexadecimal number C7 in a binary file, because the decimal 199 equals to
the hexadecimal C7
In order to perform I/O, you need to create objects using appropriate Java I/O classes: Scanner and
PrintWriter: 5 PrintWriter output = new PrintWriter("temp.txt"); output.println("Java 101");
output.close(); // to flush the output to disk Scanner input = new Scanner(new File("temp.txt"));
System.out.println(input.nextLine());
Binary I/O does not require conversions: when you write a byte to a file, the original byte is copied
into the file, and when you read a byte from a file, the exact byte in the file is returned
Page |2
• The abstract InputStream is the root class for reading binary data
• The abstract OutputStream is the root class for writing binary data
• The design of the Java I/O classes is a good example of applying inheritance, where common
operations are generalized in superclasses, and subclasses provide specialized operations.
InputStream:
• Reads the next byte of data from the input stream. The value byte is returned as an int value
in the range 0 to 255. If no byte is available because the end of the stream has been reached,
the value –1 is returned.
• Reads up to b.length bytes into array b from the input stream and returns the actual number
of bytes read. Returns -1 at the end of the stream.
• Reads bytes from the input stream and stores into b[off], b[off+1], …, b[off+len-1]. The actual
number of bytes read is returned.
• Returns -1 at the end of the stream. Returns the number of bytes that can be read from the
input stream.
• Closes this input stream and releases any system resources associated with the stream.
• Skips over and discards n bytes of data from this input stream. The actual number of bytes
skipped is returned.
• Tests if this input stream supports the mark and reset methods.
• Marks the current position in this input stream.
• Repositions this stream to the position at the time the mark method was last called on this
input stream.
Page |3
OutputStream:
• Writes the specified byte to this output stream. The parameter b is an int value. (byte)b is
written to the output stream.
• Writes all the bytes in array b to the output stream.
• Writes b[off], b[off+1], …, b[off+len-1] into the output stream.
• Closes this input stream and releases any system resources associated with the stream.
• Flushes this output stream and forces any buffered output bytes to be written out.
Object I/O
➢ DataInputStream/DataOutputStream enables you to perform I/O for primitive type
values and strings.
➢ Finally, ObjectInputStream / ObjectOutputStream enables you to perform I/O for
objects in addition for primitive type values and strings
Page |4
ObjectInputStream
➢ ObjectInputStream extends InputStream and implements ObjectInput and
ObjectStreamConstants
ObjectOutputStream
➢ ObjectOutputStream extends OutputStream and implements ObjectOutput and
ObjectStreamConstants:
Page |5
Object Streams
• You may wrap an ObjectInputStream/ObjectOutputStream on any
InputStream/OutputStream using the following constructors:
Constructor
Constructor Description
RandomAccessFile(File file, String mode) Creates a random access file stream to read from, and optionally to write to, th
argument.
RandomAccessFile(String name, String Creates a random access file stream to read from, and optionally to write to, a fil
mode)
Method
void close() It closes this random access file stream and releases any system resources
associated with the stream.
FileChannel getChannel() It returns the unique FileChannel object associated with this file.
void seek(long pos) It sets the file-pointer offset, measured from the beginning of this file, at
which the next read or write occurs.
void writeDouble(double It converts the double argument to a long using the doubleToLongBits
v) method in class Double, and then writes that long value to the file as an
eight-byte quantity, high byte first.
void writeFloat(float v) It converts the float argument to an int using the floatToIntBits method in
class Float, and then writes that int value to the file as a four-byte quantity,
high byte first.
void seek(long pos) It sets the file-pointer offset, measured from the beginning of this file, at
which the next read or write occurs.
Example
1. import java.io.IOException;
2. import java.io.RandomAccessFile;
3.
4. public class RandomAccessFileExample {
5. static final String FILEPATH ="myFile.TXT";
6. public static void main(String[] args) {
7. try {
8. System.out.println(new String(readFromFile(FILEPATH, 0, 18)));
9. writeToFile(FILEPATH, "I love my country and my people", 31);
10. } catch (IOException e) {
11. e.printStackTrace();
12. }
13. }
14. private static byte[] readFromFile(String filePath, int position, int size)
15. throws IOException {
16. RandomAccessFile file = new RandomAccessFile(filePath, "r");
17. file.seek(position);
18. byte[] bytes = new byte[size];
Page |7
19. file.read(bytes);
20. file.close();
21. return bytes;
22. }
23. private static void writeToFile(String filePath, String data, int position)
24. throws IOException {
25. RandomAccessFile file = new RandomAccessFile(filePath, "rw");
26. file.seek(position);
27. file.write(data.getBytes());
28. file.close();
29. }
Multithreading in Java
Multithreading in Java is a process of executing multiple threads simultaneously.
However, we use multithreading than multiprocessing because threads use a shared memory
area. They don't allocate separate memory area so saves memory, and context-switching
between the threads takes less time than process.
1) It doesn't block the user because threads are independent and you can perform multiple
operations at the same time.
o Each process has an address in memory. In other words, each process allocates a
separate memory area.
o A process is heavyweight.
Page |8
Threads are independent. If there occurs exception in one thread, it doesn't affect other
threads. It uses a shared memory area.
1. New
Page |9
2. Active
3. Blocked / Waiting
4. Timed Waiting
5. Terminated
New: Whenever a new thread is created, it is always in the new state. For a thread in the new
state, the code has not been run yet and thus has not begun its execution.
Active: When a thread invokes the start() method, it moves from the new state to the active
state. The active state contains two states within it: one is runnable, and the other is running.
o Runnable: A thread, that is ready to run is then moved to the runnable state. In the runnable
state, the thread may be running or may be ready to run at any given instant of time. It is the
duty of the thread scheduler to provide the thread time to run, i.e., moving the thread the
running state.
o Running: When the thread gets the CPU, it moves from the runnable to the running
state. Generally, the most common change in the state of a thread is from runnable
to running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time (not permanently) then,
either the thread is in the blocked state or is in the waiting state.
For example, a thread (let's say its name is A) may want to print some data from the printer.
However, at the same time, the other thread (let's say its name is B) is using the printer to
print some data. Therefore, thread A has to wait for thread B to use the printer. Thus, thread
A is in the blocked state. A thread in the blocked state is unable to perform any execution and
thus never consume any cycle of the Central Processing Unit (CPU). Hence, we can say that
thread A remains idle until the thread scheduler reactivates thread A, which is in the waiting
or blocked state.
Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its name
is A) has entered the critical section of a code and is not willing to leave that critical section.
Terminated: A thread reaches the termination state because of the following reasons:
o When a thread has finished its job, then it exists or terminates normally.
o Abnormal termination: It occurs when some unusual events such as an unhandled
exception or segmentation fault.
A terminated thread means the thread is no more in the system. In other words, the thread
is dead, and there is no way one can respawn (active after kill) the dead thread.
P a g e | 10
The following diagram shows the different states involved in the life cycle of a thread.
In Java, one can get the current state of a thread using the Thread.getState() method.
The java.lang.Thread.State class of Java provides the constants ENUM to represent the state
of a thread. These constants are:
It represents the runnable state.It means a thread is waiting in the queue to run.
It represents the blocked state. In this state, the thread is waiting to acquire a lock.
Runnable Interface
Java runnable is an interface used to execute code on a concurrent thread. It is an interface
which is implemented by any class if we want that the instances of that class should be
executed by a thread.
The runnable interface has an undefined method run() with void as return type, and it takes
in no arguments. The method summary of the run() method is given below-
P a g e | 11
Method Description
public void This method takes in no arguments. When the object of a class implementing Runnable class
run() is used to create a thread, then the run method is invoked in the thread which executes
separately.
• The runnable interface provides a standard set of rules for the instances of classes
which wish to execute code when they are active. The most common use case of the
Runnable interface is when we want only to override the run method. When a thread
is started by the object of any class which is implementing Runnable, then it invokes
the run method in the separately executing thread.
• A class that implements Runnable runs on a different thread without subclassing
Thread as it instantiates a Thread instance and passes itself in as the target. This
becomes important as classes should not be subclassed unless there is an intention of
modifying or enhancing the fundamental behavior of the class.
• Runnable class is extensively used in network programming as each thread represents
a separate flow of control. Also in multi-threaded programming, Runnable class is
used. This interface is present in java.lang package.
Implementing Runnable
It is the easiest way to create a thread by implementing Runnable. One can create a thread
on any object by implementing Runnable. To implement a Runnable, one has only to
implement the run method.
Output:
There are several differences between Thread class and Runnable interface based on their
performance, memory usage, and composition.
o Runnable makes the code more flexible as, if we are extending a thread, then our code
will only be in a thread whereas, in case of runnable, one can pass it in various executor
services, or pass it to the single-threaded environment.
o Maintenance of the code is easy if we implement the Runnable interface.
Synchronization in Java
Synchronization in Java is the capability to control the access of multiple threads to any shared
resource.
Java Synchronization is better option where we want to allow only one thread to access the
shared resource.
Types of Synchronization
1. Process Synchronization
2. Thread Synchronization
Thread Synchronization
There are two types of thread synchronization mutual exclusive and inter-thread
communication.
1. Mutual Exclusive
1. Synchronized method.
2. Synchronized block.
3. Static synchronization.
2. Cooperation (Inter-thread communication in java)
P a g e | 14
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. It
can be achieved by using the following three ways:
Synchronized Method
TestSynchronization2.java
23. }
24. class MyThread2 extends Thread{
25. Table t;
26. MyThread2(Table t){
27. this.t=t;
28. }
29. public void run(){
30. t.printTable(100);
31. }
32. }
33.
34. public class TestSynchronization2{
35. public static void main(String args[]){
36. Table obj = new Table();//only one object
37. MyThread1 t1=new MyThread1(obj);
38. MyThread2 t2=new MyThread2(obj);
39. t1.start();
40. t2.start();
41. }
42. }
Output:
5
10
15
20
25
100
200
300
400
500
Synchronized Block in Java
Synchronized block can be used to perform synchronization on any specific resource of the
method.
Suppose we have 50 lines of code in our method, but we want to synchronize only 5 lines, in
such cases, we can use synchronized block.
Syntax
P a g e | 16
Exception
Dictionary Meaning: Exception is an abnormal condition.
In Java, an exception is an event that disrupts the normal flow of the program. It is an object
which is thrown at runtime.
1. try{
2. //code that may throw an exception
3. }catch(Exception_class_Name ref){}
1. try{
2. //code that may throw an exception
3. }finally{}
P a g e | 17
catch block
➢ Java catch block is used to handle the Exception by declaring the type of exception
within the parameter. The declared exception must be the parent class exception (
i.e., Exception) or the generated exception type. However, the good approach is to
declare the generated type of exception.
➢ The catch block must be used after the try block only. You can use multiple catch block
with a single try block.
The JVM firstly checks whether the exception is handled or not. If exception is not handled,
JVM provides a default exception handler that performs the following tasks:
Example 2
TryCatchExample2.java
Output:
java.lang.ArithmeticException: / by zero
rest of the code
finally block
➢ Java finally block is a block used to execute important code such as closing the
connection, etc.
➢ Java finally block is always executed whether an exception is handled or not.
Therefore, it contains all the necessary statements that need to be printed regardless
of the exception occurs or not.
➢ The finally block follows the try-catch block.
• finally block in Java can be used to put "cleanup" code such as closing a file, closing
connection, etc.
• The important statements to be printed can be placed in the finally block.
Let's see the the fillowing example. Here, the code throws an exception however the catch
block cannot handle it. Despite this, the finally block is executed after the try block and then
the program terminates abnormally.
TestFinallyBlock1.java
Output:
P a g e | 20