commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michele Mazzucco <Michele.Mazzu...@ncl.ac.uk>
Subject Re: [io] new ThresholdingOutputStream implementation
Date Mon, 11 Sep 2006 07:46:01 GMT
JIRA IO-92 created.

Michele

Stephen Colebourne wrote:
> Sounds interesting. Can you raise a JIRA call for this (enhancement) and
> attach the changes to it? That way we won't lose it. Thanks
> Stephen
> 
> Michele Mazzucco wrote:
>> Hi all,
>>
>> I've extended the ThresholdingOutputStream class with a new class which
>> behaves different from DeferredFileOutputStream:
>> - when the stream is closed, the content stored in memory is *always*
>> flushed to disk (in DeferredFileOutputStream, instead, if the treshold
>> is not reached data is lost)
>> - DeferredFileOutputStream maintains data in memory only until the
>> treshold value has been reached, then it immediately writes every byte
>> to disk. Mine implementation, instead, caches treshold bytes in memory,
>> and every time that value is reached (that is, treshold, 2 * threshold,
>> etc), it flushes data to disk. In other words it acts as a cache.
>>
>> Please find attached the class together with the unit test.
>>
>>
>>
>> Best regards,
>> Michele
>>
>>
>> ------------------------------------------------------------------------
>>
>> /*
>>  * Licensed to the Apache Software Foundation (ASF) under one or more
>>  * contributor license agreements.  See the NOTICE file distributed with
>>  * this work for additional information regarding copyright ownership.
>>  * The ASF licenses this file to You under the Apache License, Version
>> 2.0
>>  * (the "License"); you may not use this file except in compliance with
>>  * the License.  You may obtain a copy of the License at
>>  *  *      http://www.apache.org/licenses/LICENSE-2.0
>>  *  * Unless required by applicable law or agreed to in writing, software
>>  * distributed under the License is distributed on an "AS IS" BASIS,
>>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> implied.
>>  * See the License for the specific language governing permissions and
>>  * limitations under the License.
>>  */
>>
>> package org.apache.commons.io.output;
>>
>> import java.io.DataInputStream;
>> import java.io.File;
>> import java.io.FileInputStream;
>> import java.io.FileNotFoundException;
>> import java.io.IOException;
>> import java.util.Arrays;
>>
>> import junit.framework.TestCase;
>>
>> /**
>>  * JUnit test case for {@link DeferredPeriodicOutputStream}.
>>  *  * @author <a href="mailto:Michele.Mazzucco@ncl.ac.uk">Michele
>> Mazzucco</a>
>>  *
>>  */
>> public class DeferredPeriodicOutputStreamTest extends TestCase {
>>     
>>     
>>     /**
>>      * The test data as a string (which is the simplest form).
>>      */
>>     private String testString = "0123456789";
>>
>>     /**
>>      * The test data as a byte array, derived from the string.
>>      */
>>     private byte[] testBytes = testString.getBytes();
>>
>>     
>>     /**
>>      * Standard JUnit test case constructor.
>>      *      * @param name
>>      *            The name of the test case.
>>      */
>>     public DeferredPeriodicOutputStreamTest(String name) {
>>         super(name);
>>     }
>>     
>>     
>>     /**
>>      * Tests the case where the amount of data falls below the
>> threshold, and is
>>      * therefore confined to memory.
>>      */
>>     public void testBelowThreshold() {
>>         File testFile = getTestFile("testBelowTreshold.dat");
>>        
>>         DeferredPeriodicOutputStream dpos =
>>                 new DeferredPeriodicOutputStream(testBytes.length +
>> 42, testFile);
>>         try {
>>             dpos.write(testBytes, 0, testBytes.length);
>>             dpos.close();
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>
>>         byte[] resultBytes = dpos.getData();
>>         assertEquals(0, resultBytes.length);
>>                 verifyResultFile(testFile);
>>     }
>>     
>>         /**
>>      * Tests the case where the amount of data is exactly the same as the
>>      * threshold. The behavior should be the same as that for the
>> amount of
>>      * data being below (i.e. not exceeding) the threshold.
>>      */
>>     public void testAtThreshold() {
>>         File testFile = getTestFile("testAtThreshold.dat");
>>        
>>         DeferredPeriodicOutputStream dpos =
>>                 new DeferredPeriodicOutputStream(testBytes.length,
>> testFile);
>>         try
>>         {
>>             dpos.write(testBytes, 0, testBytes.length);
>>             dpos.close();
>>         }
>>         catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>
>>         byte[] resultBytes = dpos.getData();
>>         assertEquals(0, resultBytes.length);
>>         verifyResultFile(testFile);
>>     }
>>         /**
>>      * Tests the case where the amount of data exceeds the threshold,
>> and is
>>      * therefore written to disk. The actual data written to disk is
>> verified,
>>      * as is the file itself.
>>      */
>>     public void testAboveThreshold() {
>>         File testFile = getTestFile("testAboveThreshold.dat");
>>                 DeferredFileOutputStream dfos =
>>                 new DeferredFileOutputStream(testBytes.length - 5,
>> testFile);
>>         try
>>         {
>>             dfos.write(testBytes, 0, testBytes.length);
>>             dfos.close();
>>         }
>>         catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>         assertFalse(dfos.isInMemory());
>>         assertNull(dfos.getData());
>>
>>         verifyResultFile(testFile);
>>     }
>>         /**
>>      * Verifies that the specified file contains the same data as the
>> original
>>      * test data.
>>      *
>>      * @param testFile The file containing the test output.
>>      */
>>     private void verifyResultFile(File testFile) {
>>         try
>>         {
>>             FileInputStream fis = new FileInputStream(testFile);
>>             assertTrue(fis.available() == testBytes.length);
>>
>>             byte[] resultBytes = new byte[testBytes.length];
>>             assertTrue(fis.read(resultBytes) == testBytes.length);
>>
>>             assertTrue(Arrays.equals(resultBytes, testBytes));
>>             assertTrue(fis.read(resultBytes) == -1);
>>
>>             try
>>             {
>>                 fis.close();
>>             }
>>             catch (IOException e) {
>>                 // Ignore an exception on close
>>             }
>>         }
>>         catch (FileNotFoundException e) {
>>             fail("Unexpected FileNotFoundException");
>>         }
>>         catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>     }
>>
>>         public void testCheckThreshold() {
>>         File testFile = getTestFile("testCheckThreshold.dat");
>>        
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(8, testFile);
>>        
>>         try {
>>             dpos.write(testBytes);
>>             dpos.close();
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>         assertTrue(dpos.isThresholdExceeded());
>>     }
>>
>>     private static File getTestFile(String path) {
>>         File testFile = new File(path);
>>         testFile.deleteOnExit();
>>         testFile.delete();
>>        
>>         return testFile;
>>     }
>>
>>     public void testGetStream() {
>>         File testFile = getTestFile("testGetStream.dat");
>>        
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(12, testFile);
>>         try {
>>             dpos.write(testBytes);
>>             byte[] memory = dpos.getData();
>>             assertEquals(memory.length, 10);
>>             assertTrue(Arrays.equals(testBytes, memory));
>>            
>>             dpos.close();
>>             memory = dpos.getData();
>>             assertEquals(memory.length, 0);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>     }
>>
>>     /**
>>      * Tests the write of a int value.
>>      */
>>     public void testWriteInt() {
>>         File testFile = getTestFile("testWriteInt.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(5, testFile);
>>        
>>         try {
>>             dpos.writeInt(5);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         int read = getInt(dpos.getData());       
>>         assertTrue(read == 5);
>>     }
>>
>>     /**
>>      * Tests the write of a float value.
>>      */
>>     public void testWriteFloat() {
>>         File testFile = getTestFile("testWriteFloat.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(9, testFile);
>>        
>>         try {
>>             dpos.writeFloat(15.65f);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         float read = getFloat(dpos.getData());       
>>         assertTrue(read == 15.65f);
>>     }
>>
>>     /**
>>      * Tests the write of a long value.
>>      */
>>     public void testWriteLong() {
>>         File testFile = getTestFile("testWriteLong.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(9, testFile);
>>        
>>         long value = System.currentTimeMillis();
>>         try {
>>             dpos.writeLong(value);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         float read = getLong(dpos.getData());
>>         assertTrue(read == value);
>>     }
>>
>>     /**
>>      * Tests the write of a double value.
>>      */
>>     public void testWriteDouble() {
>>         File testFile = getTestFile("testWriteDouble.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(9, testFile);
>>        
>>         try {
>>             dpos.writeDouble(Math.PI);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         double read = getDouble(dpos.getData());       
>>         assertTrue(read == Math.PI);
>>     }
>>
>>
>>     /**
>>      * Tests the write of a char value.
>>      */
>>     public void testWriteChar() {
>>         File testFile = getTestFile("testWriteChar.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(3, testFile);
>>        
>>         try {
>>             dpos.writeChar('b');
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         char c = getChar(dpos.getData());       
>>         assertTrue(c == 'b');
>>     }
>>
>>     /**
>>      * Tests the write of a boolean value.
>>      */
>>     public void testWriteBoolean() {
>>         File testFile = getTestFile("testWriteBoolean.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(2, testFile);
>>        
>>         try {
>>             dpos.writeBoolean(true);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         boolean read = (dpos.getData()[0] != 0);       
>>         assertTrue(read == true);
>>     }
>>
>>     
>>     /**
>>      * Tests the write of a byte value.
>>      */
>>     public void testWriteByte() {
>>         File testFile = getTestFile("testWriteByte.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(2, testFile);
>>        
>>         try {
>>             dpos.writeByte(3);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         byte read = (byte) (dpos.getData()[0]);       
>>         assertTrue(read == 3);
>>     }
>>
>>     public void testWriteBytes() {
>>         File testFile = getTestFile("testWriteBytes.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(2, testFile);
>>        
>>         try {
>>             dpos.writeBytes(testString);
>>             dpos.close();
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         verifyResultFile(testFile);
>>     }
>>
>>     public void testWriteChars() {
>>         File testFile = getTestFile("testWriteChars.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(21, testFile);
>>        
>>         try {
>>             dpos.writeChars(testString);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         byte[] read = dpos.getData();
>>         char[] c = new char[10];
>>         byte[] b = new byte[2];
>>         int j = 0;
>>         for (int i = 0; i < read.length; i = (i + 2)) {           
>>             System.arraycopy(read, i, b, 0, 2);
>>             c[j] = getChar(b);
>>             j++;
>>         }
>>        
>>         assertEquals(testString, new String(c));
>>     }
>>
>>     /**
>>      * Tests the write of a short value.
>>      */
>>     public void testWriteShort() {
>>         File testFile = getTestFile("testWriteShort.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(3, testFile);
>>        
>>         try {
>>             dpos.writeShort(3);
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         short read = (short) getChar(dpos.getData());
>>         assertTrue(read == 3);
>>     }
>>
>>     /**
>>      * Tests the write of an UTF string.
>>      */
>>     public void testWriteUTF() {
>>         File testFile = getTestFile("testWriteUTF.dat");
>>         DeferredPeriodicOutputStream dpos = new
>> DeferredPeriodicOutputStream(3, testFile);
>>        
>>         try {
>>             dpos.writeUTF(testString);
>>             dpos.close();
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }
>>        
>>         try {
>>             DataInputStream dis = new DataInputStream(new
>> FileInputStream(testFile));
>>             String s = dis.readUTF();
>>            
>>             assertEquals(testString, s);
>>            
>>             try {
>>                 dis.close();
>>             } catch (IOException e) {
>>                 // Ignore this
>>             }
>>         } catch (FileNotFoundException e) {
>>             fail("Unexpected FileNotFoundException");
>>         } catch (IOException e) {
>>             fail("Unexpected IOException");
>>         }     }
>>     
>>     
>>     
>>     //===================================================================//
>>
>>     // Static methods used to convert array of bytes to primitive values
>>     //===================================================================//
>>
>>     
>>     /**
>>      * Converts the specified array of <code>bytes</code> to a
>> <code>int</code>.
>>      *      * @param b    An array of <code>bytes</code>.
>>      * @return    The equivalent <code>int</code> value.
>>      */
>>     public static int getInt(byte[] b) {
>>         assert b.length == 4: "Invalid number of bytes for integer
>> conversion";
>>         return ((b[0] << 24) & 0xFF000000) + ((b[1] << 16) &
>> 0x00FF0000) +
>>             ((b[2] << 8) & 0x0000FF00) + ((b[3] << 0) & 0x000000FF);
>>     }
>>     
>>     /**
>>      * Converts the specified array of <code>bytes</code> to a
>> <code>float</code>.
>>      *      * @param b    An array of <code>bytes</code>.
>>      * @return    The equivalent <code>float</code> value.
>>      */
>>     public static float getFloat(byte[] b) {
>>         assert b.length == 4: "Invalid number of bytes for float
>> conversion";
>>         return Float.intBitsToFloat(getInt(b));
>>     }
>>
>>     /**
>>      * Converts the specified array of <code>bytes</code> to a
>> <code>long</code>.
>>      *      * @param b    An array of <code>bytes</code>.
>>      * @return    The equivalent <code>long</code> value.
>>      */
>>     public static long getLong(byte[] b) {
>>         assert b.length == 8: "Invalid number of bytes for long
>> conversion";
>>         int high = getInt(new byte[] { b[0], b[1], b[2], b[3] });
>>         int low = getInt(new byte[] { b[4], b[5], b[6], b[7] });
>>         long value = ((long)(high) << 32) + (low & 0xFFFFFFFFL);
>>         return value;
>>     }
>>     
>>     /**
>>      * Converts the specified array of <code>bytes</code> to a
>> <code>double</code>.
>>      *      * @param b    An array of <code>bytes</code>.
>>      * @return    The equivalent <code>double</code> value.
>>      */
>>     public static double getDouble(byte[] b) {
>>         assert b.length == 8: "Invalid number of bytes for double
>> conversion";
>>         return Double.longBitsToDouble(getLong(b));
>>     }
>>     
>>     /**
>>      * Converts the specified array of <code>bytes</code> to a
>> <code>char</code>.
>>      *      * @param b    An array of <code>bytes</code>.
>>      * @return    The equivalent <code>char</code> value.
>>      */
>>     public static char getChar(byte[] b) {
>>         assert b.length == 2: "Invalid number of bytes for char
>> conversion";
>>         return (char)(((b[0] << 8) & 0x0000FF00) + ((b[1] << 0) &
>> 0x000000FF));
>>     }
>> }
>>
>>
>> ------------------------------------------------------------------------
>>
>> /*
>>  * Licensed to the Apache Software Foundation (ASF) under one or more
>>  * contributor license agreements.  See the NOTICE file distributed with
>>  * this work for additional information regarding copyright ownership.
>>  * The ASF licenses this file to You under the Apache License, Version
>> 2.0
>>  * (the "License"); you may not use this file except in compliance with
>>  * the License.  You may obtain a copy of the License at
>>  *  *      http://www.apache.org/licenses/LICENSE-2.0
>>  *  * Unless required by applicable law or agreed to in writing, software
>>  * distributed under the License is distributed on an "AS IS" BASIS,
>>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> implied.
>>  * See the License for the specific language governing permissions and
>>  * limitations under the License.
>>  */
>>
>> package org.apache.commons.io.output;
>>
>> import java.io.DataOutput;
>> import java.io.File;
>> import java.io.FileOutputStream;
>> import java.io.IOException;
>> import java.io.OutputStream;
>> import java.io.UTFDataFormatException;
>>
>>
>> /**
>>  * The <code>DeferredPeriodicOutputStream</code> is an output stream
>> which
>>  * retains data in memory until a specified treshold is reached,
>> commit it
>>  * to disk and reset the threshold value. The result is that data are
>> written
>>  * to disk on a periodic basis, that is, every <i>treshold</i> bytes.
>> In other
>>  * words, this output stream acts as a cache.
>>  * <p>
>>  * Opposite to {@link DeferredFileOutputStream}, if the stream is
>>  * closed before the threshold is reached, the data are written to
>>  * disk.
>>  *  * @author <a href="mailto:Michele.Mazzucco@ncl.ac.uk">Michele
>> Mazzucco</a>
>>  * @version $Version$
>>  * @see    org.apache.commons.io.output.DeferredFileOutputStream
>>  */
>> public class DeferredPeriodicOutputStream extends
>> ThresholdingOutputStream     implements DataOutput {
>>     
>>     
>>    
>> //=======================================================================//
>>
>>     // Instance fields
>>    
>> //=======================================================================//
>>
>>
>>
>>     /**
>>      * The output stream to which data will be written before every
>> theshold
>>      * is reached.
>>      */
>>     private ByteArrayOutputStream memoryOutputStream;
>>     
>>     /**
>>      * The output stream to which data will be written after every
>> theshold
>>      * is reached.
>>      */
>>     private FileOutputStream diskOutputStream;
>>     
>>     /**
>>      * The file to which output will be directed every time the
>> threshold is      * exceeded.
>>      */
>>     private File outputFile;
>>     
>>
>>     
>>    
>> //=======================================================================//
>>
>>     // Constructor
>>    
>> //=======================================================================//
>>
>>
>>     
>>     /**
>>      * Creates a new <tt>DeferredPeriodicOutputStream</tt> object.
>>      *
>>      * @param threshold The number of bytes to keep in memory.
>>      * @param file        The file to use every time the threshold is
>> reached.
>>      */
>>     public DeferredPeriodicOutputStream(int threshold, File file) {
>>         super(threshold);
>>         this.outputFile = file;
>>         this.memoryOutputStream = new ByteArrayOutputStream(threshold);
>>     }
>>     
>>     /**
>>      * Creates a new <tt>DeferredPeriodicOutputStream</tt> object.
>>      *
>>      * @param threshold The number of bytes to keep in memory.
>>      * @param file        The path to the file to use every time the
>> threshold      *                     is reached.
>>      */
>>     public DeferredPeriodicOutputStream(int treshold, String path) {
>>         this(treshold, new File(path));
>>     }
>>     
>>     
>>    
>> //=======================================================================//
>>
>>     // Methods from ThresholdingOutputStream
>>    
>> //=======================================================================//
>>
>>
>>
>>     /**
>>      * Gets the memory output stream (<i>always</i>).
>>      *      * @return The memory ouput stream.
>>      */
>>     @Override
>>     protected OutputStream getStream() {
>>         return memoryOutputStream;
>>     }
>>
>>     @Override
>>     protected synchronized void thresholdReached() throws IOException {
>>         if (diskOutputStream == null) {
>>             diskOutputStream = new FileOutputStream(outputFile);
>>         }
>>         memoryOutputStream.writeTo(diskOutputStream);
>>         diskOutputStream.flush();
>>         memoryOutputStream.reset();
>>     }
>>     
>>     
>>     @Override
>>     protected synchronized void checkThreshold(int count) throws
>> IOException {
>>         if ((memoryOutputStream.size() + count) > super.getThreshold()) {
>>             this.thresholdReached();
>>         }     }
>>     
>>     /**
>>      * Closes this output stream flushing all cached data to disk.
>>      */
>>     @Override
>>     public void close() throws IOException {       
>>         super.close();
>>         if (diskOutputStream == null) {
>>             if (memoryOutputStream.size() > 0) {
>>                 diskOutputStream = new FileOutputStream(outputFile);
>>             } else {
>>                 return;
>>             }
>>         }
>>        
>>         memoryOutputStream.writeTo(diskOutputStream);
>>         flush();
>>         memoryOutputStream.reset();
>>         memoryOutputStream.close();
>>        
>>         if (diskOutputStream != null) {
>>             diskOutputStream.close();
>>         }
>>     }
>>     
>>     
>>     /**
>>      * Flushes this output stream and forces any buffered output bytes
>> to be
>>      * written out.
>>      *
>>      * @exception IOException if an error occurs.
>>      */
>>     @Override
>>     public void flush() throws IOException {
>>         memoryOutputStream.flush();
>>        
>>         if (diskOutputStream != null)
>>             diskOutputStream.flush();
>>     }
>>     
>>     //
>> ======================================================================//
>>     // Public methods
>>    
>> //=======================================================================//
>>
>>
>>     
>>     
>>     /**
>>      * Returns an array of bytes containing between <code>0</code> and
>>      * {@link ThresholdingOutputStream#threshold} bytes. The array
>> corresponds
>>      * to the data cached in memory.
>>      *      * @return The data for this output stream which are
>> maintained in memory.
>>      */
>>     public byte[] getData() {
>>         return memoryOutputStream.toByteArray();
>>     }
>>     
>>     
>>    
>> //=======================================================================//
>>
>>     // Methods from java.io.DataOuput
>>    
>> //=======================================================================//
>>
>>
>>     
>>     /**
>>      * Writes an <code>int</code> to the underlying output stream as
four
>>      * bytes, high byte first. If no exception is thrown, the counter
>>      * <code>written</code> is incremented by <code>4</code>.
>>      *
>>      * @param      value   an <code>int</code> to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      */
>>     public void writeInt(int value) throws IOException {
>>         super.write(getIntBytes(value));
>>     }
>>     
>>     /**
>>      * Converts the float argument to an <code>int</code> using the
>>      * <code>floatToIntBits</code> method in class <code>Float</code>,
>>      * and then writes that <code>int</code> value to the underlying
>>      * output stream as a 4-byte quantity, high byte first. If no     
>> * exception is thrown, the counter <code>written</code> is      *
>> incremented by <code>4</code>.
>>      *
>>      * @param      value   a <code>float</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.lang.Float#floatToIntBits(float)
>>      */
>>     public void writeFloat(float value) throws IOException {
>>         writeInt(Float.floatToIntBits(value));
>>     }
>>     
>>     /**
>>      * Writes a <code>long</code> to the underlying output stream as
>> eight
>>      * bytes, high byte first. In no exception is thrown, the counter
>>      * <code>written</code> is incremented by <code>8</code>.
>>      *
>>      * @param      value   a <code>long</code> to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.io.FilterOutputStream#out
>>      */
>>     public void writeLong(long value) throws IOException {
>>         super.write(getLongBytes(value));
>>     }
>>     
>>     /**
>>      * Converts the double argument to a <code>long</code> using the
>>      * <code>doubleToLongBits</code> method in class
>> <code>Double</code>,      * and then writes that <code>long</code>
>> value to the underlying      * output stream as an 8-byte quantity,
>> high byte first. If no      * exception is thrown, the counter
>> <code>written</code> is      * incremented by <code>8</code>.
>>      *
>>      * @param      value   a <code>double</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.lang.Double#doubleToLongBits(double)
>>      */
>>     public void writeDouble(double value) throws IOException {
>>         writeLong(Double.doubleToLongBits(value));
>>     }
>>     
>>     /**
>>      * Writes a <code>char</code> to the underlying output stream as
a
>>      * 2-byte value, high byte first. If no exception is thrown, the
>>      * counter <code>written</code> is incremented by <code>2</code>.
>>      *
>>      * @param      value   a <code>char</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.io.FilterOutputStream#out
>>      */
>>     public void writeChar(int value) throws IOException {
>>         super.write(getCharBytes(value));
>>     }
>>     
>>     
>>     
>>    
>>     /**
>>      * Writes a <code>boolean</code> to the underlying output stream
>> as      * a 1-byte value. The value <code>true</code> is written out
>> as the      * value <code>(byte)1</code>; the value <code>false</code>
>> is      * written out as the value <code>(byte)0</code>. If no
>> exception is      * thrown, the counter <code>written</code> is
>> incremented by      * <code>1</code>.
>>      *
>>      * @param      value   a <code>boolean</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      */
>>     public void writeBoolean(boolean value) throws IOException {
>>         writeByte(value ? 1: 0);
>>     }
>>
>>     /**
>>      * Writes out a <code>byte</code> to the underlying output stream
>> as      * a 1-byte value. If no exception is thrown, the counter     
>> * <code>written</code> is incremented by <code>1</code>.
>>      *
>>      * @param      value   a <code>byte</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      */
>>     public void writeByte(int value) throws IOException {
>>         super.write(value);
>>     }
>>
>>     /**
>>      * Writes out the string to the underlying output stream as a     
>> * sequence of bytes. Each character in the string is written out, in
>>      * sequence, by discarding its high eight bits. If no exception is
>>      * thrown, the counter <code>written</code> is incremented by the
>>      * length of <code>s</code>.
>>      *
>>      * @param      s   a string of bytes to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @exception  NullPointerException if the <code>s</code> is
>> <code>null</code>.
>>      */
>>     public void writeBytes(String s) throws IOException {
>>         int len = s.length();
>>         for (int i = 0; i < len; i++) {
>>             super.write((byte) s.charAt(i));
>>         }
>>     }
>>     
>>
>>     /**
>>      * Writes a string to the underlying output stream as a sequence
>> of      * characters. Each character is written to the data output
>> stream as      * if by the <code>writeChar</code> method. If no
>> exception is      * thrown, the counter <code>written</code> is
>> incremented by twice      * the length of <code>s</code>.
>>      *
>>      * @param      s   a <code>String</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see           #writeChar(int)
>>      * @see           #writeBytes(String)
>>      */
>>     public void writeChars(String s) throws IOException {
>>         int len = s.length();
>>         for (int i = 0; i < len; i++) {
>>             writeChar(s.charAt(i));
>>         }
>>     }
>>
>>     /**
>>      * Writes a <code>short</code> to the underlying output stream as
two
>>      * bytes, high byte first. If no exception is thrown, the counter
>>      * <code>written</code> is incremented by <code>2</code>.
>>      *
>>      * @param      value   a <code>short</code> to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      */
>>     public void writeShort(int value) throws IOException {
>>         writeChar(value);
>>     }
>>
>>     /**
>>      * Writes a string to the underlying output stream using
>>      * <a
>> href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/DataInput.html#modified-utf-8">modified
>> UTF-8</a>
>>      * encoding in a machine-independent manner.      * <p>
>>      * First, two bytes are written to the output stream as if by the
>>      * <code>writeShort</code> method giving the number of bytes to
>>      * follow. This value is the number of bytes actually written out,
>>      * not the length of the string. Following the length, each
>> character      * of the string is output, in sequence, using the
>> modified UTF-8 encoding
>>      * for the character. If no exception is thrown, the counter     
>> * <code>written</code> is incremented by the total number of      *
>> bytes written to the output stream. This will be at least two      *
>> plus the length of <code>str</code>, and at most two plus      *
>> thrice the length of <code>str</code>.
>>      *
>>      * @param      s   a string to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      */
>>     public void writeUTF(String s) throws IOException {
>>         int len = s.length();
>>         int utflen = getUTFLen(s, len);
>>        
>>         // The byte will store the encoded string lenght (as short)
>> followed
>>         // by the stream of encoded characters
>>         byte[] b = new byte[utflen + 2];
>>        
>>         // b[0] and b[1] host the encoded string lenght
>>         System.arraycopy(getCharBytes(utflen), 0, b, 0, 2);
>>         int count = 2;
>>        
>>         char c;
>>         for (int i = 0; i < len; i++) {
>>             c = s.charAt(i);
>>     
>>             if ((c >= 0x0001) && (c <= 0x007f)) {
>>                 // one byte
>>                 b[count++] = (byte) c;
>>             } else if ((c == 0x0000) || ((c >= 0x0080) && (c <=
>> 0x07ff))) {
>>                 // two bytes
>>                 b[count++] = (byte)(0xc0 | (0x1f & (c >> 6)));
>>                 b[count++] = (byte)(0x80 | (0x3f & c));
>>             } else {
>>                 // three bytes
>>                 b[count++] = (byte)(0xe0 | (0x0f & (c >> 12)));
>>                 b[count++] = (byte)(0x80 | (0x3f & (c >>  6)));
>>                 b[count++] = (byte)(0x80 | (0x3f & c));
>>             }
>>         }
>>        
>>         super.write(b);
>>     }
>>     
>>     
>>     
>>     /**
>>      * Computes the encoded <code>string</code> lengh.
>>      *      * @param s        a <code>string</code> to convert.
>>      * @param len    The <code>string</code> lenght.
>>      * @return        The encoded <code>string</code> lenght.
>>      * @exception    UTFDataFormatException    if the encoded
>> <code>string</code>
>>      *              is longer than <code>65535</code> bytes.      */
>>     private static int getUTFLen(String s, int len) throws
>> UTFDataFormatException {
>>         int utflen = 0;
>>         char c;
>>        
>>         for (int i = 0; i < len; i++) {
>>             c = s.charAt(i);
>>             if ((c >= 0x0001) && (c <= 0x007f)) {
>>                 // the character uses one byte only
>>                 utflen++;
>>             } else if ((c == 0x0000) || ((c >= 0x0080) && (c <=
>> 0x07ff))) {
>>                 // the character uses two bytes
>>                 utflen += 2;
>>             } else {
>>                 // the character uses three bytes
>>                 utflen += 3;
>>             }
>>         }
>>        
>>         if (utflen > 65535) {
>>             throw new UTFDataFormatException(
>>                     "Encoded string too long: " + utflen + " bytes");
>>         }
>>        
>>         return utflen;
>>     }
>>
>>        
>>     
>>    
>> //=======================================================================//
>>
>>     // Static methods
>>    
>> //=======================================================================//
>>
>>     
>>     /**
>>      * Writes an <code>int</code> to the underlying output stream as
four
>>      * bytes, high byte first. If no exception is thrown, the counter
>>      * <code>written</code> is incremented by <code>4</code>.
>>      *
>>      * @param      value   an <code>int</code> to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.io.FilterOutputStream#out
>>      */
>>     public static byte[] getIntBytes(int value) {
>>         byte[] b = new byte[4];
>>         b[0] = (byte)((value >>> 24) & 0xFF);
>>         b[1] = (byte)((value >>> 16) & 0xFF);
>>         b[2] = (byte)((value >>>  8) & 0xFF);
>>         b[3] = (byte)((value >>>  0) & 0xFF);
>>         return b;
>>     }
>>
>>     /**
>>      * Writes a <code>long</code> to the underlying output stream as
>> eight
>>      * bytes, high byte first. In no exception is thrown, the counter
>>      * <code>written</code> is incremented by <code>8</code>.
>>      *
>>      * @param      value   a <code>long</code> to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.io.FilterOutputStream#out
>>      */
>>     public static byte[] getLongBytes(long value) {
>>         byte[] b = new byte[8];
>>         b[0] = (byte)((int)(value >>> 56) & 0xFF);
>>         b[1] = (byte)((int)(value >>> 48) & 0xFF);
>>         b[2] = (byte)((int)(value >>> 40) & 0xFF);
>>         b[3] = (byte)((int)(value >>> 32) & 0xFF);
>>         b[4] = (byte)((int)(value >>> 24) & 0xFF);
>>         b[5] = (byte)((int)(value >>> 16) & 0xFF);
>>         b[6] = (byte)((int)(value >>>  8) & 0xFF);
>>         b[7] = (byte)((int)(value >>>  0) & 0xFF);
>>         return b;
>>     }
>>     
>>     
>>
>>     /**
>>      * Writes a <code>char</code> to the underlying output stream as
a
>>      * 2-byte value, high byte first. If no exception is thrown, the
>>      * counter <code>written</code> is incremented by <code>2</code>.
>>      *
>>      * @param      value   a <code>char</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.io.FilterOutputStream#out
>>      */
>>     public static byte[] getCharBytes(int value) {
>>         byte[] b = new byte[2];
>>         b[0] = (byte)((value >>> 8) & 0xFF);
>>         b[1] = (byte)((value >>> 0) & 0xFF);
>>         return b;
>>     }
>>
>>     /**
>>      * Converts the double argument to a <code>long</code> using the
>>      * <code>doubleToLongBits</code> method in class
>> <code>Double</code>,      * and then writes that <code>long</code>
>> value to the underlying      * output stream as an 8-byte quantity,
>> high byte first. If no      * exception is thrown, the counter
>> <code>written</code> is      * incremented by <code>8</code>.
>>      *
>>      * @param      value   a <code>double</code> value to be written.
>>      * @exception  IOException  if an I/O error occurs.
>>      * @see        java.io.FilterOutputStream#out
>>      * @see        java.lang.Double#doubleToLongBits(double)
>>      */
>>     public static byte[] getDoubleBytes(double value) {
>>         byte[] b = getLongBytes(Double.doubleToLongBits(value));
>>         return b;
>>     }
>>     
>> }    //    END DeferredPeriodicOutputStream
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-user-help@jakarta.apache.org
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Mime
View raw message