CHAPTER 9
BINARY I/O,RECURSION AND GENERICS
SUBJECT:OOP-I PREPARED BY:
CODE:3140705 ASST.PROF.NENSI KANSAGARA
(CSE DEPARTMENT,ACET)
BINARY
I/O
INTRODUCTION TO I/O
PROGRAMMING
➔ Java I/O (Input and Output) is used to process the input and produce the output.
➔ Java uses the concept of a stream to make I/O operation fast. The java.io package contains all the
classes required for input and output operations.
➔ We can perform file handling in Java by Java I/O API
➔ In this Java File IO tutorial, we show you how to read and write binary files using both legacy File
I/O API and new File I/O API (NIO). The legacy API (classes in the java.io.* package) is perfect
for manipulating low-level binary I/O operations such as reading and writing exactly one byte at a
time, whereas the NIO API (classes in the java.nio.* package) is more convenient for reading and
writing the whole file at once, and of course, faster than the old File I/O API.
HANDLING IN JAVA
syntax:
PrintWriter o =new printwriter(“input.txt”);
o.print(“I love my country”);
Example:
Scanner i = new Scanner(new File(input.txt));
System.out.println(i.nextline());
CONCEPT OF STREAM
➔ A stream is a sequence of data. In Java, a stream is composed of bytes. It's called a stream because it is like a
stream of water that continues to flow.
➔ In Java, 3 streams are created for us automatically. All these streams are attached with the console.
◆ 1) System.out: standard output stream
◆ 2) System.in: standard input stream
◆ 3) System.err: standard error stream
➔ Let's see the code to print output and an error message to the console.
◆ System.out.println("simple message");
◆ System.err.println("error message");
➔ Let's see the code to get input from console.
int i=System.in.read();//returns ASCII code of 1st character
System.out.println((char)i);//will print the character
➔ The java.io package contains all the classes required for input output
operations.
➔ All streams represent an input source and an output destination.
➔ The stream in the java.io package supports all the datatype including
primitive.
➔ A stream can be defined as a sequence of data.
➔ There are two kinds of Streams
◆ InputStream : The InputStream is used to read data from a source.
◆ OutputStream : The OutputStream is used for writing data to a destination.
TEXT AND BINARY I/O
➔ All the programming languages provide support for standard I/O where the user's program can
take input from a keyboard and then produce an output on the computer screen. If you are aware
of C or C++ programming languages, then you must be aware of three standard devices STDIN,
STDOUT and STDERR. Similarly, Java provides the following three standard streams −
◆ Standard Input − This is used to feed the data to user's program and usually a keyboard is used
as standard input stream and represented as System.in.
◆ Standard Output − This is used to output the data produced by the user's program and usually
a computer screen is used for standard output stream and represented as System.out.
◆ Standard Error − This is used to output the error data produced by the user's program and
usually a computer screen is used for standard error stream and represented as System.err.
BINARY I/O CLASSES
FILEINPUTSTREAM
➔ Java FileInputStream class obtains input bytes from a file.
➔ It is used for reading streams of raw bytes such as image data.
➔ For reading streams of characters, consider using FileReader.
➔ It should be used to read byte-oriented data for example to
read image, audio, video etc.
Java FileInputStream class declaration
Let's see the declaration for java.io.FileInputStream class:
1. public class FileInputStream extends InputStream
FILEOUTPUTSTREAM
➔ Java FileOutputStream is an output stream for writing data to a
file.
➔ If you have to write primitive values then use FileOutputStream
But for character-oriented data, prefer FileWriter.
➔ But you can write byte-oriented as well as character-oriented
data.
Methods of fileoutputstream
FILTERINPUTSTREAM
➔ Java FilterInputStream class implements the InputStream. It contains
different sub classes as BufferedInputStream, DataInputStream for
providing additional functionality. So it is less used individually.
➔ Java FilterInputStream class declaration
➔ Let's see the declaration for java.io.FilterInputStream class
◆ public class FilterInputStream extends InputStream
FILTEROUTPUTSTREAM
➔ Java FileOutputStream is an output stream used for writing data to a file.
➔ If you have to write primitive values into a file, use FileOutputStream class. You can write
byte-oriented as well as character-oriented data through FileOutputStream class. But, for
character-oriented data, it is preferred to use FileWriter than FileOutputStream.
➔ FileOutputStream class declaration
◆ Let's see the declaration for Java.io.FileOutputStream class:
◆ public class FileOutputStream extends OutputStream
DATAINPUTSTREAM
Java DataInputStream class allows an application to read primitive data from the input stream in a
machine-independent way.
Java application generally uses the data output stream to write data that can later be read by a data input
stream.
Java DataInputStream class declaration
Let's see the declaration for java.io.DataInputStream class:
public class DataInputStream extends FilterInputStream implements DataInput
DATAOUTPUTSTREAM
➔ Java DataOutputStream class allows an application to write primitive Java data
types to the output stream in a machine-independent way.
➔ Java application generally uses the data output stream to write data that can later
be read by a data input stream.
➔ Java DataOutputStream class declaration
◆ Let's see the declaration for java.io.DataOutputStream class:
◆ public class DataOutputStream extends FilterOutputStream implements
DataOutput
BUFFEREDINPUTSTREAM
➔ Java BufferedInputStream class is used to read information from stream. It internally uses buffer
mechanism to make the performance fast.
➔ The important points about BufferedInputStream are:
◆ When the bytes from the stream are skipped or read, the internal buffer automatically refilled
from the contained input stream, many bytes at a time.
◆ When a BufferedInputStream is created, an internal buffer array is created.
➔ Java BufferedInputStream class declaration
◆ Let's see the declaration for Java.io.BufferedInputStream class:
◆ public class BufferedInputStream extends FilterInputStream
BUFFEREDOUTPUTSTREAM
➔ Java BufferedOutputStream class is used for buffering an output stream. It internally uses
buffer to store data. It adds more efficiency than to write data directly into a stream. So, it
makes the performance fast.
➔ For adding the buffer in an OutputStream, use the BufferedOutputStream class. Let's see
the syntax for adding the buffer in an OutputStream:
◆ OutputStream os= new BufferedOutputStream(new FileOutputStream("D:\\IO
Package\\testout.txt"));
➔ Java BufferedOutputStream class declaration
◆ Let's see the declaration for Java.io.BufferedOutputStream class:
◆ public class BufferedOutputStream extends FilterOutputStream
OBJECT I/O
➔ The object I/O supports ObjectInputStream and ObjectOutputStream
classes.These classes to perform I/O operations for object in addition
to primitive data types.
➔ The ObjectInputStream is a subclass of InputStream and implements
ObjectInput and ObjectStramConstant.
➔ Public ObjectInputStream(InputStream in)
➔ public ObjectOutputStream(OutputStream out)
THE SERIALIZABLE
INTERFACE
➔ Serializable is a marker interface (has no data
member and method). It is used to "mark"
Java classes so that the objects of these
classes may get a certain capability. The
Cloneable and Remote are also marker
interfaces.
➔ It must be implemented by the class whose
object you want to persist.
➔ The String class and all the wrapper classes
implement the java.io.Serializable interface
by default.
RANDOM ACCESS FILES
➔ This class is used for reading and writing to randomaccessfile. A
random access file behaves like a large array of bytes. There is a
cursor implied to the array called file pointer, by moving the cursor
we do the read write operations. If end-of-file is reached before the
desired number of byte has been read than EOFException is thrown. It
is a type of IOException.
RECURSION
PROBLEM SOLVING USING RECURSION
➔ Recursion in java is a process in which a method calls itself continuously. A
method in java that calls itself is called recursive method.
➔ It makes the code compact but complex to understand.
➔ Syntax:
◆ returntype methodname(){
◆ //code to be executed
◆ methodname();//calling same method
◆ }
RECURSIVE HELPER METHODS
1. we need one helper method where we will pass original string , prefix and
one list for result.
2. we will use recursion here. and base case is string is null, in that case we
will be returning prefix+orginal string.
3. initially prefix is null and here we will check the 1st character of string is
character or not if character we remove that character from original string
and will add the same character to prefix and will call uppercase and
lowercase method.
TAIL RECURSION
➔ A tail-recursive function is just a function whose very the last
action is a call to itself. Tail-Call Optimisation(TCO) lets us
convert regular recursive calls into tail calls to make
recursions practical for large inputs, which was earlier leading
to stack overflow error in normal recursion scenario
public class TailRecDemo{
public static void main(String []args)
fun(3);
Public static void fun(int n)
System.out.println(n);
if(n>0)
fun(n-1);
}
GENERICS
What is generic programming?
➔ Java Generic methods and generic classes enable programmers to specify,
with a single method declaration, a set of related methods, or with a single
class declaration, a set of related types, respectively.
➔ Generics also provide compile-time type safety that allows programmers to
catch invalid types at compile time.
➔ Using Java Generic concept, we might write a generic method for sorting an
array of objects, then invoke the generic method with Integer arrays, Double
arrays, String arrays and so on, to sort the array elements.
What is the need for generic?
➔ It saves the programmers burden of creating separate
methods for handling data belonging to different data
types.
➔ It allows the code reusability
➔ Compact code can be created.
Defining generic classes and interfaces
Generic methods
➔ Generic methods are methods that introduce their own type parameters.
This is similar to declaring a generic type, but the type parameter scope is
limited to the method where it is declared. Static and non-static generic
methods are allowed, as well as generic class constructors.
➔ The syntax for a generic method includes a list of type parameters, inside
angle brackets, which appears before the method's return type. For static
generic methods, the type parameter section must appear before the
method's return type.
Raw types and backward compatibility
➔ Generic class or interface is used without specifying a concrete type.
➔ It enables backward compatibility with earlier versions of java
➔ Example:
GenericsStack stack= new GenericsStack();
This is almost equivalent to
GenericsStack <Object> stack = new GenericsStack<Object>();
➔ The raw types are unsafe.
Concept of bounded type
➔ There may be times when you want to restrict the types that can be used as type arguments in a parameterized
type. For example, a method that operates on numbers might only want to accept instances of Number or its
subclasses. This is what bounded type parameters are for.
◆ Sometimes we don’t want whole class to be parameterized, in that case we can create java generics
method. Since constructor is a special kind of method, we can use generics type in constructors too.
◆ Suppose we want to restrict the type of objects that can be used in the parameterized type. For example
in a method that compares two objects and we want to make sure that the accepted objects are
Comparables.
◆ The invocation of these methods is similar to unbounded method except that if we will try to use any
class that is not Comparable, it will throw compile time error.
Wildcard generic types
➔ The question mark (?) is known as the wildcard in generic programming . It represents an
unknown type. The wildcard can be used in a variety of situations such as the type of a
parameter, field, or local variable; sometimes as a return type. Unlike arrays, different
instantiations of a generic type are not compatible with each other, not even explicitly. This
incompatibility may be softened by the wildcard if ? is used as an actual type parameter.
➔ There are three ways to use wildcards
1.Unbounded wildcard
2.Upper bound wildcard
3.Lower bound wildcard
Unbounded
wildcard
➔ These wildcards can be used
when you want to relax the
restrictions on a variable. For
example, say you want to
write a method that works on
List < integer >, List < double
>, and List < number > , you
can do this using an upper
bounded wildcard.
➔ To declare an upper-bounded
wildcard, use the wildcard
character (‘?’), followed by
the extends keyword,
followed by its upper bound.
Upper Bound
wildcard
➔ This wildcard type is specified
using the wildcard character (?),
for example, List. This is called
a list of unknown type. These
are useful in the following cases
◆ When writing a method
which can be employed
using functionality
provided in Object class.
◆ When the code is using
methods in the generic
class that don’t depend on
the type parameter
Lower Bound
wildcard
➔ It is expressed using
the wildcard character
(‘?’), followed by the
super keyword,
followed by its lower
bound: <? super A>.
◆ Syntax:
Collectiontype <?
super A>
Erasure and restrictions on generics
➔ Type Erasure rules
◆ Replace type parameters in generic type with their bound if bounded type
parameters are used.
◆ Replace type parameters in generic type with Object if unbounded type
parameters are used.
◆ Insert type casts to preserve type safety.
◆ Generate bridge methods to keep polymorphism in extended generic types.
Restrictions on generics
1. It cannot instantiate Generic Types with primitive data types.
2. It cannot create instance of Type Parameter
3. It cannot declare static field whose types are types parameter
4. It cannot use cast or instances of operators with parameterized types.
5. It cannot create Array of parameterized types.
6. It cannot create,catch or throw Objects of parameterized types.
7. It cannot overload a method where the formal parameter Types of
Each Overloaded Erase to the same Raw Type.