// "Java Tech"
// Code provided with book for educational purposes only.
// No warranty or guarantee implied.
// This code freely available. No copyright claimed.
// 2003
//
import javax.swing.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
/**
* This class contains several static methods used to
* write and read histograms to disk files. It is identical
* to HistIOTools class except for the following four
* methods, which use NIO techniques:
*
* readFile(), writeFile()
* packHistogram(), unpackHistogram()
*
**/
public class HistNIOTools {
// Create a Histogram type filter for the file chooser
private static HstFilter fHstFilter = new HstFilter ();
/**
* Use a JFileChooser in Open mode to select files
* to open. Use a filter for FileFilter subclass to select
* for *.java files. If a file is selected then read the
* file and place the string into the textarea.
**/
public static File openFile (JFrame frame) {
File file = null;
JFileChooser fc = new JFileChooser ();
fc.setDialogTitle ("Open Histogram File");
// Choose only files, not directories
fc.setFileSelectionMode (JFileChooser.FILES_ONLY);
// Start in current directory
fc.setCurrentDirectory (new File ("."));
// Set filter for web pages.
fc.setFileFilter (fHstFilter);
// Now open chooser
int result = fc.showOpenDialog (frame);
if (result == JFileChooser.CANCEL_OPTION) {
return null;
} else if (result == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile ();
} else {
return null;
}
return file;
} // openFIle
/**
* Use a JFileChooser in Save mode to select files
* to open. Use a filter for FileFilter subclass to select
* for *.java type files. If a file is selected, then write the
* the string from the textarea into it.
*
* @param frame the chooser connects to this frame component.
* @param file the inital file object for the chooser selection.
* @param histogram Histogram object for saving.
**/
public static File saveFile (JFrame frame, File file){
JFileChooser fc = new JFileChooser ();
fc.setDialogTitle ("Save Histogram");
// Start in current directory
fc.setCurrentDirectory (new File ("."));
// Set filter for web pages.
fc.setFileFilter (fHstFilter);
// Set to a default name for save.
if (file !=null) fc.setSelectedFile (file);
// Open chooser dialog
int result = fc.showSaveDialog (frame);
if (result == JFileChooser.CANCEL_OPTION) {
return null;
} else if ( result == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile ();
if (file.exists ()) {
int response = JOptionPane.showConfirmDialog (null,
"Overwrite existing file?","Confirm Overwrite",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (response == JOptionPane.CANCEL_OPTION) return null;
}
return file;
} else {
return null;
}
} // saveFIle
/**
* Use a FileChannel to read to read the histogram data
* from the given file.
*
* @param file File object from which to locate file.
**/
public static Histogram readFile (File file) {
try {
FileChannel in_chan = new FileInputStream (file).getChannel ();
// Assume histogram file sizes are always less than int max.
int num_data = (int) in_chan.size ();
ByteBuffer buffer = ByteBuffer.allocateDirect (num_data);
in_chan.read (buffer);
in_chan.close ();
return unpackHistogram (buffer);
} catch (IOException ioe ) {
JOptionPane.showMessageDialog (
null,
"Error in reading data!!\n\r"+ioe,
"Histogram File Read Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
} // readFile
/**
* Use a FileChannel to write a ByteBuffer containing the
* histogram data to the given file.
*
* @param file File object for the file to receive the histogram data.
**/
public static boolean writeFile (File file, Histogram histogram) {
ByteBuffer buffer = packHistogram (histogram);
try {
FileChannel out_chan = new FileOutputStream (file).getChannel();
out_chan.write (buffer);
out_chan.close ();
}
catch (IOException ioe) {
JOptionPane.showMessageDialog (
null,
"Error in writing data!!\n\r"+ioe,
"Histogram File Save Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
} // writeFile
/**
* Convert histogram data to a byte array
* for storage using a byte array stream.
*
* @param hist Histogram object containing data to be packed.
**/
public static ByteBuffer packHistogram (Histogram hist) {
// The write methods can throw IOExceptions so must set up
// to catch them
try {
// Need the length of the title
int num_chars_title = hist.getTitle ().length ();
// The length of the label
int num_chars_label = hist.getXLabel ().length ();
// And the bin array
int [] bins = hist.getBins ();
// Add up total buffer size. This include 3*4 = 12 for the
// title, label and bin array sizes. Also,
// under + overflow ints plus upper + lower range doubles = 24
int total_byte_size = 12 + num_chars_title*2 + num_chars_label*2 +
bins.length*4 + 24;
ByteBuffer buffer = ByteBuffer.allocateDirect (total_byte_size);
buffer.putInt (num_chars_title);
CharBuffer char_buffer = CharBuffer.wrap (hist.getTitle ());
(buffer.asCharBuffer ()).put (char_buffer);
buffer.putInt (num_chars_label);
char_buffer = CharBuffer.wrap (hist.getXLabel ());
(buffer.asCharBuffer ()).put (char_buffer);
buffer.putInt (bins.length);
IntBuffer int_buffer = IntBuffer.wrap (bins);
(buffer.asIntBuffer ()).put (int_buffer);
// Save underflow value.
buffer.putInt (hist.getValue (-1));
// Save overflow value.
buffer.putInt (hist.getValue (bins.length));
// Write the lower and upper range values
buffer.putDouble (hist.getLo ());
buffer.putDouble (hist.getHi ());
return buffer;
}
catch (BufferOverflowException e) {
JOptionPane.showMessageDialog (
null,
"Error in packing data!!\n\r" + e,
"Histogram Data Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
} // packHistogram
/** Re-build a histogram from a byte array. **/
public static Histogram unpackHistogram (ByteBuffer hist_buffer){
// The read methods can throw IOExceptions so must set up
// to catch them
try {
// First read the characters for the title
int num_chars = hist_buffer.getInt ();
char [] char_array = new char[num_chars];
for (int i=0; i < num_chars; i++) {
char_array[i] = hist_buffer.getChar ();
}
String title = String.valueOf (char_array);
// First read the characters for the horizontal label
num_chars = hist_buffer.getInt ();
char_array = new char[num_chars];
for (int i=0; i < num_chars; i++) {
char_array[i] = hist_buffer.getChar ();
}
String x_label = String.valueOf (char_array);
// Get the bin data
int num_bins = hist_buffer.getInt ();
int [] bins = new int[num_bins];
for (int i=0; i < num_bins; i++) {
bins[i] = hist_buffer.getInt ();
}
int under_flows = hist_buffer.getInt ();
int over_flows = hist_buffer.getInt ();
double lo = hist_buffer.getDouble ();
double hi = hist_buffer.getDouble ();
// Create a histogram with
Histogram hist = new Histogram (title, x_label, num_bins, lo, hi);
// Pack the rest of the data.
hist.pack (bins, under_flows, over_flows, lo, hi);
return hist;
} catch (BufferUnderflowException e) {
JOptionPane.showMessageDialog (
null,
"Error in unpacking data!!\n\r" + e,
"Histogram Data Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
} // unpackHistogram
/**
* Use a ObjectOutputStream wrapped around a FileOutputStream,
* to write a Histogram (made Serializable) to the given file.
*
* @param file File object for the file to receive the histogram data.
**/
public static boolean writeSerialFile (File file,
Histogram histogram) {
try {
ObjectOutputStream out =
new ObjectOutputStream (new FileOutputStream (file));
out.writeObject (histogram);
out.flush ();
out.close ();
}
catch (IOException ioe) {
JOptionPane.showMessageDialog (
null,
"Error in writing data object!!\n\r"+ioe,
"Histogram File Save Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
} // writeSerialFile
/**
* Use a ObjectInputStream wrapped around a FileInputStream
* to read the Histogram object (made Serializable
* from the given file.
*
* @param file File object from which to locate file.
**/
public static Histogram readSerialFile (File file) {
try {
FileInputStream in = new FileInputStream (file);
ObjectInputStream obj_in = new ObjectInputStream (in);
Histogram hist = (Histogram) (obj_in.readObject ());
obj_in.close ();
return hist;
}
catch (ClassNotFoundException notex ) {
JOptionPane.showMessageDialog (
null,
"Error in reading data!!\n\r"+notex,
"Histogram File Read Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
catch (IOException ioe ) {
JOptionPane.showMessageDialog (
null,
"Error in reading data!!\n\r"+ioe,
"Histogram File Read Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
} // readSerialFile
} // class HistNIOTools