Вы находитесь на странице: 1из 19

Files and IO Streams

Java performs I/O through Streams. A Stream is linked to a physical layer by java I/O system to
make input and output operation in java. In general, a stream means continuous flow of data. Streams
are clean way to deal with input/output without having every part of your code understand the physical.
An I/O Stream represents an input source or an output destination. A stream can represent
many different kinds of sources and destinations, including disk files, devices, other programs, and
memory arrays.
Streams support many different kinds of data, including simple bytes, primitive data types,
localized characters, and objects. Some streams simply pass on data; others manipulate and transform
the data in useful ways.
No matter how they work internally, all streams present the same simple model to programs
that use them: A stream is a sequence of data. A program uses an input stream to read data from a
source, one item at a time:

Reading information into a program.


A program uses an output stream to write data to a destination, one item at time:

Writing information from a program.


In this lesson, we'll see streams that can handle all kinds of data, from primitive values to advanced
objects.
The data source and data destination pictured above can be anything that holds, generates, or
consumes data. Obviously this includes disk files, but a source or destination can also be another
program, a peripheral device, a network socket, or an array.
Java encapsulates Stream under java.io package. Java defines two types of streams. They are,
1. Byte Stream : It provides a convenient means for handling input and output of byte.
2. Character Stream : It provides a convenient means for handling input and output of characters.
Character stream uses Unicode and therefore can be internationalized.

Byte Stream Classes


Byte stream is defined by using two abstract class at the top of hierarchy, they are InputStream and
OutputStream.
These two abstract classes have several concrete classes that handle various devices such as disk
files, network connection etc.
Some important Byte stream classes.
Stream class Description
BufferedInputStream Used for Buffered Input Stream.
BufferedOutputStream Used for Buffered Output Stream.
DataInputStream Contains method for reading java standard datatype
DataOutputStream An output stream that contain method for writing java standard data type
FileInputStream Input stream that reads from a file
FileOutputStream Output stream that write to a file.
InputStream Abstract class that describe stream input.
OutputStream Abstract class that describe stream output.
PrintStream Output Stream that contain print() and println() method
These classes define several key methods. Two most important are
1. read() : reads byte of data.
2. write() : Writes byte of data.

Character Stream Classes


Character stream is also defined by using two abstract class at the top of hierarchy, they are Reader and
Writer.

These two abstract classes have several concrete classes that handle unicode character.
Some important Charcter stream classes.
Stream class Description
BufferedReader Handles buffered input stream.
BufferedWriter Handles buffered output stream.
FileReader Input stream that reads from file.
FileWriter Output stream that writes to file.
InputStreamReader Input stream that translate byte to character
OutputStreamReader Output stream that translate character to byte.
PrintWriter Output Stream that contain print() and println() method.
Reader Abstract class that define character stream input
Writer Abstract class that define character stream output
Reading Console Input
We use the object of BufferedReader class to take inputs from the keyboard.
Overview of I/O Streams
Character Streams

Reader and Writer are the abstract superclasses for character streams in java.io. Reader
provides the API and partial implementation for readers--streams that read 16-bit characters--and
Writer provides the API and partial implementation for writers--streams that write 16-bit
characters.

Subclasses of Reader and Writer implement specialized streams and are divided into two
categories: those that read from or write to data sinks (shown in gray in the following figures)
and those that perform some sort of processing (shown in white). The figure shows the class
hierarchies for the Reader and Writer classes.

Most programs should use readers and writers to read and write information. This is because they
both can handle any character in the Unicode character set (while the byte streams are limited to
ISO-Latin-1 8-bit bytes).

Byte Streams (Binary Streams)

Programs should use the byte streams, descendants of InputStream and OutputStream, to read
and write 8-bit bytes. InputStream and OutputStream provide the API and some
implementation for input streams (streams that read 8-bit bytes) and output streams (streams that
write 8-bit bytes). These streams are typically used to read and write binary data such as images
and sounds.

As with Reader and Writer, subclasses of InputStream and OutputStream provide specialized
I/O that falls into two categories: data sink streams and processing streams. Figure 56 shows the
class hierarchies for the byte streams.

As mentioned, two of the byte stream classes, ObjectInputStream and ObjectOutputStream,


are used for object serialization.

File Manipulation
While streams are used to handle most types of I/O in Java, there are some nonstream-oriented
classes in java.io that are provided for file manipulation. Namely, the File class represents a
file on the local filesystem, while the RandomAccessFile class provides nonsequential access to
data in a file. In addition, the FilenameFilter interface can be used to filter a list of filenames.

File
The File class represents a file on the local filesystem. You can use an instance of the File
class to identify a file, obtain information about the file, and even change information about the
file. The easiest way to create a File is to pass a filename to the File constructor, like this:

new File("readme.txt")
Although the methods that the File class provides for manipulating file information are
relatively platform independent, filenames must follow the rules of the local filesystem. The
File class does provide some information that can be helpful in interpreting filenames and path
specifications. The variable separatorChar specifies the system-specific character used to
separate the name of a directory from what follows. In a Windows environment, this is a
backslash (\), while in a UNIX or Macintosh environment it is a forward slash (/). File separator
can be obtained as System.getProperty('file.separator'), which is how the File class gets it. You
can create a File object that refers to a file called readme.txt in a directory called myDir as
follows:

new File("myDir" + File.separatorChar + "readme.txt")

The File class also provides some constructors that make this task easier. For example, there is a
File constructor that takes two strings as arguments: the first string is the name of a directory
and the second string is the name of a file. The following example does the exact same thing as
the previous example:

new File("myDir", "readme.txt")

The File class has another constructor that allows you to specify the directory of a file using a
File object instead of a String:

File dir = new File("myDir");

File f = new File(dir, "readme.txt");

Sometimes a program needs to process a list of files that have been passed to it in a string. For
example, such a list of files is passed to the Java environment by the CLASSPATH environment
variable and can be accessed by the expression:

System.getProperty("java.class.path")

This list contains one or more filenames separated by separator characters. In a Windows or
Macintosh environment, the separator character is a semicolon (;), while in a UNIX
environment, the separator character is a colon (:). The system-specific separator character is
specified by the pathSeparatorChar variable. Thus, to turn the value of CLASSPATH into a
collection of File objects, we can write:

StringTokenizer s;

Vector v = new Vector();

s = new StringTokenizer(System.getProperty("java.class.path"),
File.pathSeparator);

while (s.hasMoreTokens())

v.addElement(new File(s.nextToken()));
You can retrieve the pathname of the file represented by a File object with getPath(), the
filename without any path information with getName(), and the directory name with
getParent().

The File class also defines methods that return information about the actual file represented by a
File object. Use exists() to check whether or not the file exists. isDirectory() and
isFile() tell whether the file is a file or a directory. If the file is a directory, you can use
list() to get an array of filenames for the files in that directory. The canRead() and
canWrite() methods indicate whether or not a program is allowed to read from or write to a file.
You can also retrieve the length of a file with length() and its last modified date with
lastModified().

A few File methods allow you to change the information about a file. For example, you can
rename a file with rename() and delete it with delete(). The mkdir() and mkdirs() methods
provide a way to create directories within the filesystem.

Many of these methods can throw a SecurityException if a program does not have permission
to access the filesystem, or particular files within it. If a SecurityManager has been installed,
the checkRead() and checkWrite() methods of the SecurityManager verify whether or not
the program has permission to access the filesystem.

The RandomAccessFile class would not live up to its name if it did not provide a way to access
a file in a nonsequential manner. The getFilePointer() method returns the current position in
the file, while the seek() method provides a way to set the position. Finally, the length()
method returns the length of the file in bytes.

The File Class

 The java.io.File class represents a file name on the host system.

 It attempts to abstract system-dependent file name features like the path separator character.
 There are two ways to reference a file, relative and absolute.
 Absolute addressing gives a complete path to a file, starting with the disk and working its way down.
 How this is represented varies from operating system to operating system.
 Here are some examples:

o Unix: "/home/users/elharo/file1"

o DOS: "C:\home\users\elharo\file1"

o Mac OS 9: "Macintosh HD:home:users:elharo:file1"

 java.io.File can hold a directory name equally as well as a filename.


 File Constructors
o public File(String path)
o public File(String path, String name)
o public File(File dir, String name)
 File Methods
o public String getName()
o public String getPath()
o public String getAbsolutePath()
o public String getParent()
o public boolean exists() throws SecurityException
o public boolean canWrite() throws SecurityException
o public boolean canRead() throws SecurityException
o public boolean isFile() throws SecurityException
o public boolean isDirectory() throws SecurityException
o public boolean isAbsolute()
o public long lastModified() throws SecurityException
o public long length() throws SecurityException
o public boolean mkdir()
o public boolean mkdirs() throws SecurityException
o public boolean renameTo(File destination) throws SecurityException
o public boolean delete() throws SecurityException

Examples of the File Methods

import java.io.*;

public class FileInfo {


public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
File f = new File(args[i]);
if (f.exists()) {
System.out.println("getName: " + f.getName());
System.out.println("getPath: " + f.getPath());
System.out.println("getAbsolutePath: " + f.getAbsolutePath());
System.out.println("getParent: " + f.getParent());
if (f.canWrite()) {
System.out.println(f.getName() + " is writable.");
}
if (f.canRead()) {
System.out.println(f.getName() + " is readable.");
}
if (f.isFile()) {
System.out.println(f.getName() + " is a file.");
}
else if (f.isDirectory()) {
System.out.println(f.getName() + " is a directory.");
}
else {
System.out.println("What is this?");
}
if (f.isAbsolute()) {
System.out.println(f.getName() + " is an absolute path.");
}
else {
System.out.println(f.getName() + " is not an absolute path.");
}
try {
System.out.println("Last Modified" + f.lastModified());
System.out.println(f.getName() + " is " + f.length() + " bytes.");
}
catch (IOException ex) {
}
}
else {
System.out.println("Can't find the file " + args[i]);
}
}
}
}

RandomAccessFile
The RandomAccessFile class provides a way to read from and write to a file in a
nonsequential manner. The RandomAccessFile class has two constructors that both take two
arguments. The first argument specifies the file to open, either as a String or a File object. The
second argument is a String that must be either "r" or "rw". If the second argument is "r", the
file is opened for reading only. If the argument is "rw", however, the file is opened for both
reading and writing. The close() method closes the file. Both constructors and all the methods
of the RandomAccessFile class can throw an IOException if they encounter an error.

The RandomAccessFile class defines three different read() methods for reading bytes
from a file. The RandomAccessFile class also implements the DataInput interface, so it
provides additional methods for reading from a file. Most of these additional methods are related
to reading Java primitive types in a machine-independent way. Multibyte quantities are read
assuming the most significant byte is first and the least significant byte is last. All of these
methods handle an attempt to read past the end of file by throwing an EOFException.

The RandomAccessFile class also defines three different write() methods for writing
bytes of output. The RandomAccessFile class also implements the DataOutput interface, so it
provides additional methods for writing to a file. Most of these additional methods are related to
writing Java primitive types in a machine-independent way. Again, multibyte quantities are
written with the most significant byte first and the least significant byte last.

Reading Characters
read() method is used with BufferedReader object to read characters. As this function returns integer
type value has we need to use typecasting to convert it into char type.

int read() throws IOException

Below is a simple example explaining character input.

class CharRead
{
public static void main( String args[])
{
BufferedReader br = new Bufferedreader(new InputstreamReader(System.in));
char c = (char)br.read(); //Reading character
}
}

Reading Strings
To read string we have to use readLine() function with BufferedReader class's object.

String readLine() throws IOException

Program to take String input from Keyboard in Java

import java.io.*;
class MyInput
{
public static void main(String[] args)
{
String text;
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
text = br.readLine(); //Reading String
System.out.println(text);
}
}
Program to read from a file using BufferedReader class

import java. Io *;
class ReadTest
{
public static void main(String[] args)
{
try
{
File fl = new File("d:/myfile.txt");
BufferedReader br = new BufferedReader(new FileReader(fl)) ;
String str;
while ((str=br.readLine())!=null)
{
System.out.println(str);
}
br.close();
fl.close();
}
catch (IOException e)
{ e.printStackTrace(); }
}
}

Program to write to a File using FileWriter class

import java. Io *;
class WriteTest
{
public static void main(String[] args)
{
try
{
File fl = new File("d:/myfile.txt");
String str="Write this string to my file";
FileWriter fw = new FileWriter(fl) ;
fw.write(str);
fw.close();
fl.close();
}
catch (IOException e)
{ e.printStackTrace(); }
}
}
Byte Streams
Programs use byte streams to perform input and output of 8-bit bytes. All byte stream classes are
descended from InputStream and OutputStream .
There are many byte stream classes. To demonstrate how byte streams work, we'll focus on the file I/O
byte streams, FileInputStream and FileOutputStream . Other kinds of byte streams are used in much
the same way; they differ mainly in the way they are constructed.
Using Byte Streams
We'll explore FileInputStream and FileOutputStream by examining an example program named
CopyBytes , which uses byte streams to copy xanadu.txt , one byte at a time.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyBytes {


public static void main(String[] args) throws IOException {

FileInputStream in = null;
FileOutputStream out = null;

try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;

while ((c = in.read()) != -1) {


out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}

CopyBytes spends most of its time in a simple loop that reads the input stream and writes the
output stream, one byte at a time, as shown in the following figure.
Simple byte stream input and output.
Always Close Streams
Closing a stream when it's no longer needed is very important — so important that CopyBytes uses a
finally block to guarantee that both streams will be closed even if an error occurs. This practice helps
avoid serious resource leaks.
One possible error is that CopyBytes was unable to open one or both files. When that happens,
the stream variable corresponding to the file never changes from its initial null value. That's why
CopyBytes makes sure that each stream variable contains an object reference before invoking close .
#1. Program to display the Name, parent, attributes and the length of a given file.

import java.io.*;
public class FileTest
{
public static void main(String args[]) throws Exception
{
File f1=new File("hello.txt");
if(f1.exists())
{
System.out.println(f1.getName());
System.out.println(f1.getParent());
System.out.println(f1.canWrite());
System.out.println(f1.canRead());
System.out.println(f1.length());
}
else {
System.out.println("file not existed");
}
}
}

#2. Program to check whether file or directory for a given file.

import java.io.*;
public class FileStream2
{
public static void main(String args[]) throws Exception
{
File f1=new File("c:/bea");
String a[]=f1.list();
int x=a.length;
System.out.println("no of dirs and files are "+ x);

for(int i=0;i<x;i++)
{
String fname=a[i];
File f2=new File(f1,fname);
if(f2.isDirectory())
System.out.println(fname+" "+" is Directory");
if(f2.isFile())
System.out.println(fname+" "+" is File");
}
}
}
#3. program on streams by using ByteArrayInputStream

import java.io.*;
public class FileStream3
{
public static void main(String args[]) throws Exception
{
String str="welcome to Streems";
byte b[]=str.getBytes();
ByteArrayInputStream bis=new ByteArrayInputStream(b);
System.out.println(bis);
int x;
while((x=bis.read())!=-1)
{
System.out.println((char)x);
}
}
}

#4. program on streams by using ByteArrayOutputStream

import java.io.*;

public class FileStream4


{
public static void main(String args[]) throws Exception
{
ByteArrayOutputStream bos=new ByteArrayOutputStream();
String str="welcome to Streems";
byte b[]=str.getBytes();

bos.write(b);
System.out.println(bos);
}
}

#5. program to copy the file from one object to another by using ByteArrayOutputStream

import java.io.*;
public class FileStream5
{
public static void main(String args[]) throws Exception
{
ByteArrayOutputStream bos1=new ByteArrayOutputStream();
ByteArrayOutputStream bos2=new ByteArrayOutputStream();
String str="welcome to Streems";
byte b[]=str.getBytes();
bos1.write(b);
bos1.writeTo(bos2);
System.out.println(bos2);
}
}

#6. program to copy the contents from one file to another by using FileInput and FileOutputStream

import java.io.*;
public class FileStream6
{
public static void main(String args[]) throws IOException
{
System.out.println("enter path and filename");
DataInputStream dis=new DataInputStream(System.in);
String path=dis.readLine();
File f1=new File(path);

FileInputStream fis=new FileInputStream(f1);


System.out.println("enter the location");
String cpath=dis.readLine();
File f2=new File(cpath);
FileOutputStream fos=new FileOutputStream(f2);
int k;
while((k=fis.read())!=-1)
{
System.out.print((char)k);
fos.write(k);
}
}
}
#7. Program to read the contents of a given files from command-line arguments by using FileInput
and FileOutputStream

import java.io.*;
public class FileStream7
{
public static void main(String args[]) throws Exception
{
if(args.length==0)
System.out.println("enter atleast one file");
else
{
for(int i=0;i<args.length;i++)
{
FileInputStream fis=new FileInputStream(args[i]);
System.out.println("-------"+args[i]+"---------");
int k;
while((k=fis.read())!=-1)
{
System.out.print((char)k);
}
}
System.out.println("end of the file");
}
}
}

#8. Program to read the data from keyboard and stores into the file by using FileOutputStream

import java.io.*;
public class FileStream9
{
public static void main(String args[]) throws Exception
{
FileOutputStream fos=new FileOutputStream("pqr.txt");
System.out.println("enter data end type *");
char ch=(char)System.in.read();

while(ch!='*')
{
fos.write((byte)ch);
ch=(char)System.in.read();
}
}
}

#9. Program to read the data from keyboard and stores into the file by using FileOutputStream

import java.io.*;
public class FileStream10
{

public static void main(String args[]) throws IOException


{
String str;
DataInputStream dis=new DataInputStream(System.in);
System.out.println("enter a string");
str=dis.readLine();
System.out.println(str);
dis.close();
}

}
Serialization- Reading and Writing Objects
Java provides two very powerful classes to read and write objects. The ObjectOutputStream
and the ObjectInputStream, with methods readObject() and writeObject() respectively.

public final Object readObject() throws ClassNotFoundException, IOException

public final void writeObject() throws IOException

Only objects that implement the java.io.Serializable interface can be written or read using
these methods. The Serializable interface has no methods; it only acts a flag to indicate that a
class may be serialized.

The usual way to save data for an application is to wrap it up in one object and then save that
object. Example: the code to save an object, myObject, to a file called "data.obj" is as follows:
ObjectOutputStream out =
new ObjectOutputStream( new FileOutputStream("data.obj") );
out.writeObject(myObject);
out.close();

Reading the object back is also one line of code. The readObject() method returns an Object.
This has to be cast to the object's type.
ObjectInputStream in =
new ObjectInputStream( new FileInputStream("data.obj") );
ObjectType obj = (ObjectType) in.readObject();
in.close();

Exceptions
I/O methods are always prone to failure, e.g. file does not exist, or a file is closed, or disk fault.
Therefore most code that does any I/O is usually wrapped in a try..catch statement.
Alternatively, the method header carries the appropriate throws clause to delegate the error
higher up the method call stack.
The most common exceptions are IOException, and ClassNotFoundException when using the
readObject() method.
The class below wraps the object i/o code into two utility methods.

import java.io.*;

class ObjectFileUtility {

/* Writes an object to the named file. */


public static void saveObject(Serializable obj, String filename)
throws IOException
{
ObjectOutputStream oos =
new ObjectOutputStream( new FileOutputStream(filename) );

oos.writeObject(obj);
oos.flush();
oos.close();
}

/* Returns the object saved in filename.


* Hides some of the exception handling by re-throwing any
* ClassNotFoundException as an IOException.
*/
public static Object loadObject(String filename) throws IOException
{
ObjectInputStream ois =
new ObjectInputStream(
new FileInputStream(filename)
);

try
{
Object obj = ois.readObject();
ois.close();
return obj;
}
catch (ClassNotFoundException e) {
throw new IOException("ClassNotFoundException");
}
}
}

Вам также может понравиться