File Handling using Input-Output Streams in Java

        Java provides an extensive library of classes for managing input and output of all forms of data. These classes are built around a stream model. You can think of a stream as a sequence of characters (in the case of textual data) or bytes (in the case of binary data) that can be accessed in order. A stream can represent many different kinds of sources and destinations, disk files, devices, other programs, etc. Streams support many different kinds of data simple bytes, primitive data types, localized characters, and objects. Some streams simply pass on data; others manipulate and transform the data in useful ways. Data is transferred to devices by streams. There is a better approach created to File handling using input output Stream in Java.
The goal of InputStream and OutputStream is to abstract different ways to input and output: whether the stream is a file, a web page, or the screen shouldn't matter. All that matters is that you receive information from the stream. The java.io package contains a full set of Input and Output streams; Java programs use input streams to read data from some input source and output streams to write data to some output source. Input and output sources can be anything that can contain data: a file, a string, or memory.

Java views a file as a stream of bytes. File ends with end-of-file marker or a specific byte number. File as a stream of bytes associated with an object.
 
Java also associates streams with devices 
  •      System.in, System.out, and System.err 
  •      Streams can be redirected
You would typically first read from the input stream and then close it. You can wrap the FileInputStream in another InputStream (or Reader). It will be automatically closed when you close the wrapping stream/reader.

Java I/O Stream can be defined as below 3 types:

1. Byte Streams

Programs use byte streams to perform input and output of 8-bit bytes. Byte Streams classes are rooted as
  • InputStream
  • OutputStream
There are many byte stream classes for example FileInputStream and FileOutputStream. Following example shows how to use these classes to copy file.

Example to copy a file
 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(“myfile.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(); }  
   }} }  
Important Methods
  • int read() : Reads a byte of data from this input stream
  • int read(byte[] b) : Reads up to b.length bytes of data from this input stream into an array of bytes
  • void write (int b) : Writes the specified byte to this file output stream.
  • void write(byte[] b) : Writes b.length bytes from the specified byte array to this file output stream.
  • void close() : Closes the file input and output streams and releases any system resources associated with the stream

2. Character Streams

The Java platform stores character values using Unicode conventions. Character stream I/O automatically translates this internal format to and from the local character set. A program that uses character streams in place of byte streams automatically adapts to the local character set. Root Classes for Character Streams
  • Reader Class
  • Writer Class (both are abstract)
Character streams are often “wrappers” for byte streams. The character stream uses the byte stream to perform the physical I/O, while the character stream handles translation between characters and bytes. FileReader, for example, uses FileInputStream, while FileWriter uses FileOutputStream.

Copy Characters Example
 import java.io.FileReader;  
  import java.io.FileWriter;  
 import java.io.IOException;  
 public class CopyCharacters {  
   public static void main(String[] args) throws IOException {  
   FileReader inputStream = null;  
   FileWriter outputStream = null;  
    try {  
     inputStream = new FileReader(“myfile.txt");  
     outputStream = new FileWriter("characteroutput.txt");  
     int c;  
     while ((c = inputStream.read()) != -1)  
        { outputStream.write(c); }  
     } finally {  
        if (inputStream != null)  
       { inputStream.close();  
       } if (outputStream != null)  
       { outputStream.close();  
   } } } }  
Input and Output Streams
Can read from these streams. Root classes of all input streams:
  • The InputStream Class
  • The Reader Class
Output or sink (destination) streams. Can write to these streams. Root classes of all output streams:
  • The OutputStream Class
  • The Writer Class
Control Flow of an I/O operation
  1. Create a stream object and associate it with a datasource (data-destination)
  2. Give the stream object the desired functionality through stream chaining while (there is more information)
  3. read(write) next data from(to) the stream
  4. close the stream

3. Buffered Streams

The examples shown so far use unbuffered I/O. This means each read or write request is handled directly by the underlying OS. This can make a program much less efficient, since each such request often triggers disk access, network activity, or some other operation that is relatively expensive. To reduce this kind of overhead, the Java platform implements buffered I/O streams. Buffered input streams read data from a memory area known as a buffer. Similarly, buffered output streams write data to a buffer. A program can convert an unbuffered stream into a buffered stream using the wrapping.
 inputStream = new BufferedReader(new FileReader("xanadu.txt"));  
 outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));  
Example
There are four buffered stream classes used to wrap unbuffered streams:
  • BufferedInputStream
  • BufferedOutputStream (create buffered byte streams )
  • BufferedReader
  • BufferedWriter (create buffered character streams )
Flushing Buffered Streams
It often makes sense to write out a buffer at critical points, without waiting for it to fill. This is known as flushing the buffer. To flush a stream manually, invoke its flush method. The flush method is valid on any output stream, but has no effect unless the stream is buffered. Some buffered output classes support autoflush, specified by an optional constructor argument. When autoflush is enabled, certain key events cause the buffer to be flushed. For example, an autoflush PrintWriter object flushes the buffer on every invocation of println or format
CopyLine Example
 import java.io.FileReader;  
 import java.io.FileWriter;  
  import java.io.BufferedReader;  
 import java.io.PrintWriter;  
 import java.io.IOException;  
 public class CopyLines { public static void main(String[] args) throws IOException {  
 BufferedReader  inputStream = null;  
 PrintWriter  outputStream = null;  
 try {  
   inputStream = new BufferedReader(new FileReader("xanadu.txt"));  
   outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));  
 String l;  
  while ((l = inputStream.readLine()) != null) {  
   outputStream.println(l); }  
   } finally { if (inputStream != null)  
     { inputStream.close(); } if (outputStream != null)  
     { outputStream.close(); } } } }  
I/O from the Command Line
The Java platform supports three Standard Streams:
  • Standard Input, accessed through System.in;
  • Standard Output, accessed through System.out; and
  • Standard Error, accessed through System.err
These standard streams are byte streams. To use Standard Input as a character stream, wrap System.in in InputStreamReader.

ReadingLine Example
 import java.io.*;  
 public class ReadString {  
   public static void main (String[] args) {  
       System.out.print("Enter your name: ");  
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  
    String  userName = null;  
    // read the username from the command-line;  
    try {  
      userName = br.readLine();  
    } catch (IOException ioe) {  
        System.out.println("IO error trying to read your name!");  
        System.exit(1);  
    }  
    System.out.println("Thanks for the name, " + userName);  
   }  
 } // end of ReadString class  

Hope you get better understanding from above article about Java I/O streams.

Read More...

JSch: SCP a File in Java

If you want to upload a file to another computer, SCP is an excellent way to go. And if you want to do it from within a Java program, your best bet is to use the JSch library from JCraft. They've implemented the SSH protocol purely in Java, and it works splendidly. I've written a nice little class that encapsulates the action of sending a file.

Using the class is pretty simple. It goes like this:
 FileSender fs = new FileSender("172.16.40.128", "user", "user");  
 boolean ret = fs.sendFile("/home/sschulte/Desktop/AllPhysics.wmv", "AllPhysics.wmv");  
The constructor takes a host, a username, and a password. The sendFile() method takes a source filename and a destination filename. It returns true if the upload was successful, false if it failed.

I developed it in Netbeans, and in order to use JSch, the first step is to download the JAR and add it as a library in your project. (When I first tried it, I downloaded the ZIP instead, and added the source to my project; this works, but it's not necessary to compile this library along with your project unless you plan to edit it. I didn't.)

Most of the code in this class is taken from the ScpTo example included in the ZIP file. I recommend reading it. Something to pay close attention to, however, is the SSH known_hosts file. Their example file doesn't take this into account, so if you just run their code, you get an unknown host exception and it doesn't work. So be sure to include the following:
 String knownHostsFilename = "/home/sschulte/.ssh/known_hosts";  
 jsch.setKnownHosts(knownHostsFilename);  
(This is, of course, after you instantiate your JSch object.)

I like it, and it works. But it definitely needs a few things before I'm satisfied.
  • Read the known_hosts filename from a config file, rather than compiling it into the code.
  • Have a config file for the host/username/password information, possibly for multiple hosts at once.
  • Throw exceptions for various types of failures, rather that simply returning false.
Read More...