December 20, 2014
Hot Topics:

FileChannel Objects in Java, Using View Objects for Different Types

  • October 29, 2002
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

Run the Program

If you haven't already done so, I encourage you to copy the code from Listing 17 into your text editor, compile it, and execute it.  Experiment with it, making changes, and observing the results of your changes.

Remember, however, that you must be running Java version 1.4.0 or later to compile and execute this program.

Summary

In this lesson, I have shown you how to use the FileChannel class, the ByteBuffer class, the DoubleBuffer class, and the ShortBuffer class to transfer data of type double and data of type short between the computer's memory and a physical file. You have also learned how to extend the concept to any primitive data type other than boolean.

You have learned how to create different primitive views of a ByteBuffer object and how to manipulate the data in the buffer using the primitive views.

You have learned that changes made to the view objects are reflected in the ByteBuffer object and vice versa.  You have also learned that those changes are also reflected in the array object from which the ByteBuffer object was created in the first place.

What's Next?

In the next lesson, I will show you how to use the FileChannel class along with the ByteBuffer class to create records consisting of sequences of data values of mixed primitive types, and how to transfer those records between the computer's memory and a physical file.

In a lesson following that one, I will teach you how to do memory-mapped IO using channels.

Future plans

As time goes on, I plan to publish additional lessons that will help you learn to use other new IO features including:

  • File locks
  • Character-set encoders and decoders
  • Pattern matching on files using regular expressions
  • Socket channels for both clients and servers
  • Non-blocking reads
  • Non-blocking servers

Complete Program Listing

A complete listing of the program discussed in this lesson is shown in Listing 17 below.
 
/* File Channel02.java
Copyright 2002, R.G.Baldwin
Revised 9/19/02

Illustrates use of FileChannel objects
to write and read data of different 
types from a disk file.

Writes and then reads data using a
DoubleBuffer view of a ByteBuffer.

Then writes and reads data using a
ShortBuffer view of a ByteBuffer.

Tested using JDK 1.4.0 under Win2000

The output is:

Data for dBuf-raw data
0.3333333333333333
0.6666666666666666
1.0
1.3333333333333333
1.6666666666666667
2.0

Bytes written = 48
File length = 48
Clear bBuf
Data for dBuf
0.0
0.0
0.0
0.0
0.0
0.0

Bytes read = 48
File length = 48
Data for dBuf
0.3333333333333333
0.6666666666666666
1.0
1.3333333333333333
1.6666666666666667
2.0

Clear bBuf
Data for sBuf-raw data
32767
16383
10922
8191
6553
5461

Bytes written = 12
File length = 12
Clear bBuf
Data for sBuf
0
0
0
0
0
0

Bytes read = 12
File length = 12
Data for sBuf
32767
16383
10922
8191
6553
5461

**************************************/

import java.io.*;
import java.nio.channels.*;
import java.nio.*;

class Channel02{
  public static void main(
                        String[] args){
 
    //Create a ByteBuffer with a 
    // capacity of 56 bytes, and all
    // elements initialized to zero.
    ByteBuffer bBuf = 
        ByteBuffer.wrap(new byte[56]);
        
    //Get a DoubleBuffer view of the
    // ByteBuffer object
    DoubleBuffer dBuf = 
                 bBuf.asDoubleBuffer();
                                  
    //Populate the DoubleBuffer with
    // six double values.  Set its 
    // limit to the number of double
    // values stored there.  Force the
    // limit of the ByteBuffer to track
    // the limit of the DoubleBuffer.
    // Note that it is necessary to 
    // take the number of bytes in a 
    // double into account when setting
    // the limit on the ByteBuffer.
    int cnt = 0;
    for(cnt = 0; cnt < 6; cnt++){
      dBuf.put((cnt+1.0)/3);
    }//end for loop
    dBuf.limit(cnt);
    bBuf.limit(dBuf.limit()*8);

    //Display the data in the 
    // DoubleBuffer
    showDoubleBufferData(
                 dBuf,"dBuf-raw data");
                 
    //Get a File object to represent
    // a physical file.  Will use it
    // later to get the file length.
    String fileName = "junk.txt"; 
    File file = new File(fileName);
    
    //Declare variables for use later
    FileOutputStream oStr;
    FileInputStream iStr;
    FileChannel fileChan;

    //Get FileChannel for output
    try{
      oStr = new FileOutputStream(
                             fileName);
      fileChan = oStr.getChannel();

      //Write output data from the
      // ByteBuffer to the disk file.
      System.out.println(
               "Bytes written = " 
               + fileChan.write(bBuf));
      //Close stream and channel
      oStr.close();
      fileChan.close();
      //Display file length
      System.out.println(
                     "File length = " +
                        file.length());
      
      //Clear the ByteBuffer, which in
      // turn will clear the 
      // DoubleBuffer.
      clearByteBufferData(bBuf,"bBuf");

      //Display the DoubleBuffer to 
      // confirm that it has been
      // cleared.
      showDoubleBufferData(
                          dBuf,"dBuf");

      //Get FileChannel for input
      iStr = new FileInputStream(
                             fileName);
      fileChan = iStr.getChannel();

      //Read data from disk file into
      // ByteBuffer.  Then display data
      // in the DoubleBuffer.
      System.out.println(
                "Bytes read = " 
                + fileChan.read(bBuf));
      //Close stream and channel
      iStr.close();
      fileChan.close();
      //Display file length
      System.out.println(
                      "File length = " 
                      + file.length());

      //Display data
      showDoubleBufferData(
                          dBuf,"dBuf");
                          
      //Now repeat the process using 
      // the same ByteBuffer and the
      // same disk file, but using a
      // ShortBuffer view and 
      // populating the buffer with
      // primitive short data.
        
      clearByteBufferData(bBuf,"bBuf");
              
      //Get a DoubleBuffer view of the
      // ByteBuffer object
      ShortBuffer sBuf = 
                  bBuf.asShortBuffer();
      //Populate the ShortBuffer with
      // six short values.  Set its 
      // limit to the number of short
      // values stored there. Force the
      // limit of the ByteBuffer to 
      // track the limit of the 
      // ShortBuffer.
      // Note that it is necessary to 
      // take the number of bytes in a 
      // short into account when 
      // setting the limit on the 
      // ByteBuffer.

      for(cnt = 0; cnt < 6; cnt++){
        sBuf.put(
               (short)(32767/(cnt+1)));
      }//end for loop
      sBuf.limit(cnt);
      bBuf.limit(sBuf.limit()*2);

      //Display the data in the 
      // ShortBuffer
      showShortBufferData(
                 sBuf,"sBuf-raw data");
    
      //Get FileChannel for output
      oStr = new FileOutputStream(
                             fileName);
      fileChan = oStr.getChannel();

      //Write output data from the
      // ByteBuffer to the disk file.
      System.out.println(
               "Bytes written = " 
               + fileChan.write(bBuf));
      //Close stream and channel
      oStr.close();
      fileChan.close();
      //Display file length
      System.out.println(
                      "File length = " 
                      + file.length());

      //Clear the ByteBuffer, which in
      // turn will clear the 
      // ShortBuffer.
      clearByteBufferData(bBuf,"bBuf");

      //Display the ShortBuffer to 
      // confirm that it has been
      // cleared.
      showShortBufferData(
                          sBuf,"sBuf");

      //Get FileChannel for input
      iStr = new FileInputStream(
                             fileName);
      fileChan = iStr.getChannel();

      //Read data from disk file into
      // ByteBuffer.  Then display data
      // in the ShortBuffer.
      System.out.println(
                "Bytes read = " 
                + fileChan.read(bBuf));
      //Close stream and channel
      iStr.close();
      fileChan.close();
      //Display file length
      System.out.println(
                      "File length = " 
                      + file.length());

      //Display data
      showShortBufferData(sBuf,"sBuf");
      
    }catch(Exception e){
      System.out.println(e);}
  }// end main

  //---------------------------------//
  static void showDoubleBufferData(
        DoubleBuffer buf, String name){
    //Displays buffer contents
    
    //Save position
    int pos = buf.position();
    //Set position to zero
    buf.position(0);
    System.out.println(
                   "Data for " + name);
    while(buf.hasRemaining()){
      System.out.println(buf.get());
    }//end while loop
    System.out.println();//new line
    //Restore position and return
    buf.position(pos);
  }//end showDoubleBufferData
  //---------------------------------//

  static void showShortBufferData(
         ShortBuffer buf, String name){
    //Displays buffer contents
    
    //Save position
    int pos = buf.position();
    //Set position to zero
    buf.position(0);
    System.out.println(
                   "Data for " + name);
    while(buf.hasRemaining()){
      System.out.println(buf.get());
    }//end while loop
    System.out.println();//new line
    //Restore position and return
    buf.position(pos);
  }//end showShortBufferData
  //---------------------------------//
  
  static void clearByteBufferData(
          ByteBuffer buf, String name){
    //Stores 0 in each element of a
    // byte buffer.
    
    //Set position to zero
    buf.position(0);
    System.out.println(
                      "Clear " + name);
    while(buf.hasRemaining()){
      buf.put((byte)0);
    }//end while loop
    //Set position to zero and return
    buf.position(0);
  }//end clearByteBufferData
  //---------------------------------//
  
}//end class Channel02 definition

Listing 17

Copyright 2002, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects, and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which has gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com

-end-
 



Page 3 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel