You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/10/14 18:00:48 UTC

svn commit: r825175 - in /commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime: Descriptor.java io/FileInstance.java io/FileStream.java io/Stream.java io/Syncable.java

Author: mturk
Date: Wed Oct 14 16:00:47 2009
New Revision: 825175

URL: http://svn.apache.org/viewvc?rev=825175&view=rev
Log:
Add Stream base class for bidirectional streams. FileInstance will be rewritten

Added:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileStream.java   (with props)
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Stream.java   (with props)
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Syncable.java   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Descriptor.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileInstance.java

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Descriptor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Descriptor.java?rev=825175&r1=825174&r2=825175&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Descriptor.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Descriptor.java Wed Oct 14 16:00:47 2009
@@ -20,6 +20,7 @@
 import java.io.Flushable;
 import java.io.IOException;
 import java.io.SyncFailedException;
+import org.apache.commons.runtime.io.Syncable;
 
 /** Represents the Operating System object descriptor.
  * <p>
@@ -33,7 +34,7 @@
  * </p>
  * @since Runtime 1.0
  */
-public abstract class Descriptor implements Closeable, Flushable
+public abstract class Descriptor implements Closeable, Flushable, Syncable
 {
 
     /* Last error operation.

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileInstance.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileInstance.java?rev=825175&r1=825174&r2=825175&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileInstance.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileInstance.java Wed Oct 14 16:00:47 2009
@@ -42,7 +42,7 @@
  * position of the next read or write operation can be moved forwards and
  * backwards after every operation.
  */
-public class FileInstance implements Closeable, Flushable
+public class FileInstance extends Stream
 {
     /* File's descriptor object
      */
@@ -64,11 +64,22 @@
     {
         return fd;
     }
+
+    @Override
+    public boolean valid()
+    {
+        if (fd != null)
+            return fd.valid();
+        else
+            return false;
+    }
+
     /**
      * Close this file.
      * @see java.io.Closeable#close()
      * @throws IOException if an I/O error occurs.
      */
+    @Override
     public final void close()
         throws IOException
     {
@@ -89,6 +100,7 @@
      * @throws SyncFailedException when the object cannot be flushed.
      * @throws IOException if an I/O error occurs.
      */
+    @Override
     public final void flush()
         throws SyncFailedException, IOException
     {
@@ -109,6 +121,7 @@
      * @throws SyncFailedException when the object cannot be flushed.
      * @throws IOException if an I/O error occurs.
      */
+    @Override
     public final void sync()
         throws SyncFailedException, IOException
     {
@@ -288,6 +301,7 @@
      * @throws IOException
      *          If some other I/O error occurs.
      */
+    @Override
     public boolean isBlocking()
         throws IOException
     {

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileStream.java?rev=825175&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileStream.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileStream.java Wed Oct 14 16:00:47 2009
@@ -0,0 +1,1317 @@
+/* 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.runtime.io;
+
+import org.apache.commons.runtime.Descriptor;
+import org.apache.commons.runtime.Pointer;
+import org.apache.commons.runtime.exception.ClosedDescriptorException;
+import org.apache.commons.runtime.exception.AsyncClosedDescriptorException;
+import org.apache.commons.runtime.exception.InvalidDescriptorException;
+import org.apache.commons.runtime.exception.OverlappingFileLockException;
+import org.apache.commons.runtime.exception.TimeoutException;
+import org.apache.commons.runtime.util.StringManager;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.SyncFailedException;
+import java.nio.ByteBuffer;
+import java.util.Enumeration;
+import java.util.EnumSet;
+import java.util.Vector;
+
+/**
+ * Allows reading from and writing to a file in a random-access manner.
+ * This is different from the uni-directional sequential access that a
+ * {@code FileInputStream} or {@code FileOutputStream} provides. If the file is
+ * opened in read/write mode, write operations are available as well. The
+ * position of the next read or write operation can be moved forwards and
+ * backwards after every operation.
+ */
+public class FileStream extends Stream
+{
+    /* File's descriptor object
+     */
+    private Descriptor fd;
+    /* File's object lock
+     */
+    private Object sync = new Object();
+    /*
+     * List of all lock regions to this file.
+     */
+    private Vector<FileLockImpl> locks = new Vector<FileLockImpl>(2);
+
+    /**
+     * Return the {@link Descriptor} accosicated with this file.
+     *
+     * @return file's Descriptor object
+     */
+    public Descriptor fd()
+    {
+        return fd;
+    }
+
+    @Override
+    public boolean valid()
+    {
+        if (fd != null)
+            return fd.valid();
+        else
+            return false;
+    }
+
+    /**
+     * Close this file.
+     * @see java.io.Closeable#close()
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public final void close()
+        throws IOException
+    {
+        fd.close();
+    }
+
+    /**
+     * Flush the underlying file metadata.
+     * <p>
+     * {@code flush} transfers  all modified metadata of the file object
+     * referred to by {@code this} file to the disk device
+     * (or other permanent storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public final void flush()
+        throws SyncFailedException, IOException
+    {
+        fd.flush();
+    }
+
+    /**
+     * Sync the underlying file by writing any buffered data.
+     * <p>
+     * {@code sync} transfers  all  modified in-core data of the file object
+     * referred to by {@code this} file to the disk device
+     * (or other permanent storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public final void sync()
+        throws SyncFailedException, IOException
+    {
+        fd.sync();
+    }
+
+    public FileStream(File file, EnumSet<FileOpenMode> mode)
+        throws FileNotFoundException, IOException, IllegalArgumentException,
+               SecurityException
+    {
+        fd = FileWrapper.open(file, mode);
+        if (fd == null) {
+            // File exists and EXCL mode was given
+            throw new FileNotFoundException(Local.sm.get("file.EEXIST"));
+        }
+    }
+
+    public FileStream(File file, EnumSet<FileOpenMode> mode,
+                                 EnumSet<FileProtection> prot)
+        throws FileNotFoundException, IOException, IllegalArgumentException,
+               SecurityException
+    {
+        fd = FileWrapper.open(file, mode, prot);
+        if (fd == null) {
+            // File exists and EXCL mode was given
+            throw new FileNotFoundException(Local.sm.get("file.EEXIST"));
+        }
+    }
+
+    /** Create new FileStream object from the {@code fd}.
+     */
+    public FileStream(Descriptor fd)
+    {
+        this.fd = fd;
+    }
+
+    /**
+     * Clear the file errors.
+     * <p>
+     * Method clears all pending file errors and resets the
+     * end-of-file mark.
+     * </p>
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public void clearerr()
+        throws IOException
+    {
+        FileWrapper.clearerr(fd);
+        fd.clearerr();
+    }
+
+    /**
+     * Test the end-of-file indicator.
+     *
+     * @return {@code true} if end-of-file was reached.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public boolean eof()
+        throws IOException
+    {
+        return FileWrapper.eof(fd);
+    }
+
+    /**
+     * Test the file blocking mode.
+     *
+     * @return {@code true} if file operations are blocking.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    @Override
+    public boolean isBlocking()
+        throws IOException
+    {
+        return FileWrapper.blocking(fd);
+    }
+
+    /**
+     * Set file timeout.
+     *
+     * @param timeout
+     *          File timeout value in miliseconds.
+     * @return {@code true} if timeout was set. {@code false}
+     *         if file was opened in blocking mode.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public boolean setTimeout(int timeout)
+        throws IOException
+    {
+        return FileWrapper.tmset(fd, timeout);
+    }
+
+    /**
+     * Get file timeout.
+     *
+     * @return Current file timeout value in miliseconds.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int getTimeout()
+        throws IOException
+    {
+        return FileWrapper.tmget(fd);
+    }
+
+    /**
+     * Get file type.
+     *
+     * @return This file {@code FileType}.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     * @see FileType
+     */
+    public FileType getFileType()
+        throws IOException
+    {
+        return FileWrapper.ftype(fd);
+    }
+
+    /**
+     * Return cannonical file path.
+     * <p>
+     * Returned path is in Operating system cannonical form with all relative
+     * path elements removed. Depending on the Operating system this method
+     * either returns the real operating system file name, or tranformed file
+     * name by combining the currect working directory path and file path at the
+     * the time of file creation.
+     * </p>
+     *
+     * @return Cannonical file path.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public String getPath()
+        throws IOException
+    {
+        return FileWrapper.name(fd);
+    }
+
+    private boolean regionOverlaps(long offset, long length)
+    {
+        for (Enumeration<FileLockImpl> e = locks.elements(); e.hasMoreElements();) {
+            try {
+                FileLockImpl lck = e.nextElement();
+                /* Check if we already have the valid lock
+                 * for the requested region.
+                 */
+                if (lck.isValid()) {
+                    if (lck.overlaps(offset, length)) {
+                        return true;
+                    }
+                }
+                else {
+                    locks.remove(lck);
+                }
+            } catch (Throwable te) {
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return new {@link FileInfo} object.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the lock
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public FileInfo stat()
+        throws IOException, SecurityException
+    {
+        return FileWrapper.stat(fd);
+    }
+
+    /**
+     * Lock the entire file.
+     * <p>
+     * To simulate the {@link java.nio.channels.FileChannel#tryLock} use
+     * the {@link FileLockType#NONBLOCK} type.
+     * </p>
+     *
+     * @param type
+     *          {@code FileLockType} to acquire.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the lock
+     *          operation is in progress.
+     * @throws TimeoutException
+     *          If lock operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     * @see FileLock#release
+     */
+    public FileLock lock(EnumSet<FileLockType> type)
+        throws OverlappingFileLockException, IOException
+    {
+        if (regionOverlaps(0L, -1L)) {
+            /* We already have at least one lock, so we cannot
+             * lock the entire file.
+             */
+            throw new OverlappingFileLockException();
+        }
+
+        FileWrapper.lock(fd, type);
+        FileLockImpl lock = new FileLockImpl(fd, type);
+        /* Add the FileLock to the list of locks
+         */
+        locks.add(lock);
+        return lock;
+    }
+
+    /**
+     * Lock the file region.
+     * <p>
+     * Locking a region of file gives a locking process exclusive access to
+     * the specified file region. Locking can go beyond the end of the current
+     * file. This is useful to coordinate adding records to the end of file.
+     * </p>
+     * <p>
+     * <b>Warning:</b>
+     * <br/>
+     * Locks may not overlap and existing region of the file.
+     * </p>
+     *
+     * @param type
+     *          {@code FileLockType} to acquire.
+     * @param offset
+     *          The offset in bytes where the lock should begin.
+     * @param length
+     *          The length of the byte region to be locked.
+     *
+     * @throws IllegalArgumentException
+     *          If {@code offset < 0} or {@code length < 0}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the lock
+     *          operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     * @see FileLock#release
+     */
+    public FileLock lock(EnumSet<FileLockType> type, long offset, long length)
+        throws OverlappingFileLockException, IllegalArgumentException,
+               IOException
+    {
+        if (offset < 0 || length < 0 || offset < length) {
+            // unlock position is negative
+            throw new IllegalArgumentException();
+        }
+        if (regionOverlaps(offset, length)) {
+            /* We already have locked overlapping region.
+             */
+            throw new OverlappingFileLockException();
+        }
+        FileLockImpl lock = new FileLockImpl(fd, type, offset, length);
+        /* Add the FileLock to the list of locks
+         */
+        locks.add(lock);
+        return lock;
+    }
+
+    /**
+     * Moves this file's file pointer to a new position, from where following
+     * {@code read}, {@code write} or {@code skip} operations are done. The
+     * position may be greater than the current length of the file, but the
+     * file's length will only change if the moving of the pointer is followed
+     * by a {@code write} operation.
+     *
+     * @param pos
+     *          The new file pointer position.
+     * @throws IllegalArgumentException
+     *          If {@code pos < 0}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the set
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public void setFilePointer(long pos)
+        throws IllegalArgumentException, IOException
+    {
+        if (pos < 0) {
+            // seek position is negative
+            throw new IllegalArgumentException();
+        }
+        synchronized (sync) {
+            FileWrapper.seek(fd, FileSeekMethod.SET.valueOf(), pos);
+        }
+    }
+
+    /**
+     * Moves this file's file pointer to a new position, from where following
+     * {@code read}, {@code write} or {@code skip} operations are done.
+     *
+     * @param moveMethod
+     *          Starting point for the file pointer move.
+     * @param off
+     *          Move offset in bytes.
+     *
+     * @throws IllegalArgumentException
+     *          If {@code moveMethod == FileSeekMethod.SET} and
+     *          {@code off < 0}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while this
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     * @see FileSeekMethod
+     */
+    public void moveFilePointer(FileSeekMethod moveMethod, long off)
+        throws IOException
+    {
+        if (moveMethod == FileSeekMethod.SET && off < 0L) {
+            // seek position is negative
+            throw new IllegalArgumentException();
+        }
+        synchronized (sync) {
+            FileWrapper.seek(fd, moveMethod.valueOf(), off);
+        }
+    }
+
+    /**
+     * Skips over {@code count} bytes in this file. Less than {@code count}
+     * bytes are skipped if the end of the file is reached or an exception is
+     * thrown during the operation. Nothing is done if {@code count} is
+     * negative.
+     *
+     * @param count
+     *          The number of bytes to skip.
+     *
+     * @return The number of bytes actually skipped.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while this
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int skipBytes(int count)
+        throws IOException
+    {
+        if (count > 0) {
+            synchronized (sync) {
+                long cur = FileWrapper.seek(fd, FileSeekMethod.CUR.valueOf(), 0L);
+                long eof = FileWrapper.seek(fd, FileSeekMethod.END.valueOf(), 0L);
+
+                int cnt = (int)((cur + count > eof) ? eof - cur : count);
+                FileWrapper.seek(fd, FileSeekMethod.SET.valueOf(), cnt);
+                return cnt;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the current position within this file. All reads and
+     * writes take place at the current file pointer position.
+     *
+     * @return the current offset in bytes from the beginning of the file.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the get
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long getFilePointer()
+        throws IOException
+    {
+        return FileWrapper.seek(fd, FileSeekMethod.CUR.valueOf(), 0L);
+    }
+
+    /**
+     * Returns the length of this file in bytes.
+     *
+     * @return the file's length in bytes.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while this
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long length()
+        throws IOException
+    {
+        synchronized (sync) {
+            long cur = FileWrapper.seek(fd, FileSeekMethod.CUR.valueOf(), 0L);
+            long end = FileWrapper.seek(fd, FileSeekMethod.END.valueOf(), 0L);
+
+            FileWrapper.seek(fd, FileSeekMethod.SET.valueOf(), cur);
+            return end;
+        }
+    }
+
+    /**
+     * Sets the length of this file to {@code newLength}. If the current file is
+     * smaller, it is expanded but the contents from the previous end of the
+     * file to the new end are undefined. The file is truncated if its current
+     * size is bigger than {@code newLength}. If the current file pointer
+     * position is in the truncated part, it is set to the end of the file.
+     *
+     * @param newLength
+     *            the new file length in bytes.
+     * @throws IllegalArgumentException
+     *          If {@code newLength < 0}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the set
+     *          operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public void setLength(long newLength)
+        throws IllegalArgumentException, IOException
+    {
+        if (newLength < 0) {
+            throw new IllegalArgumentException();
+        }
+        synchronized (sync) {
+            FileWrapper.trunc(fd, newLength);
+        }
+    }
+
+    /**
+     * Reads a single byte from the current position in this file and returns
+     * it as an integer in the range from 0 to 255. Returns {@code -1} if the
+     * end of the file has been reached. Blocks until one byte has been read,
+     * the end of the file is detected or an exception is thrown.
+     *
+     * @return The byte read or {@code -1} if the end of the file has been reached.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *          operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int read()
+        throws IOException
+    {
+        return FileWrapper.read(fd);
+    }
+
+    /**
+     * Reads bytes from the current position in this file and stores them in the
+     * byte array {@code buffer}. The maximum number of bytes read corresponds
+     * to the size of {@code buffer}. Blocks until at least one byte has been
+     * read if the file is in blocking mode.
+     *
+     * @param buffer
+     *            The byte array in which to store the bytes read.
+     * @return The number of bytes actually read or {@code -1} if the end of
+     *         the file has been reached.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *             if this file is closed or another I/O error occurs.
+     */
+    public int read(byte[] buffer)
+        throws IOException
+    {
+        if (buffer.length == 0) {
+            return 0;
+        }
+        return FileWrapper.read(fd, buffer, 0, buffer.length);
+    }
+
+    /**
+     * Reads at most {@code count} bytes from the current position in this file
+     * and stores them in the byte array {@code buffer} starting at
+     * {@code offset}. Blocks until {@code count} bytes have been read,
+     * the end of the file is reached or an exception is thrown.
+     *
+     * @param buffer
+     *          The array in which to store the bytes read from this file.
+     * @param offset
+     *          The initial position in {@code buffer} to store the bytes read
+     *          from this file.
+     * @param count
+     *          The maximum number of bytes to store in {@code buffer}.
+     * @return The number of bytes actually read or {@code -1} if the end of
+     *         the stream has been reached.
+     *
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code buffer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int read(byte[] buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (buffer.length - offset) || count < 0 || offset < 0)
+            throw new IndexOutOfBoundsException();
+        if (count == 0) {
+            /* Returning zero usually represents a timeout.
+             */
+            return 0;
+        }
+        return FileWrapper.read(fd, buffer, offset, count);
+    }
+
+    /**
+     * Reads bytes from the current position in this file and stores them in the
+     * {@code pointer}. The maximum number of bytes read corresponds
+     * to the size of {@code pointer}. Blocks until at least one byte has been
+     * read if the file is in blocking mode.
+     *
+     * @param pointer
+     *            The {@code Pointer} in which to store the bytes read.
+     * @return The number of bytes actually read or {@code -1} if the end of
+     *         the file has been reached.
+     *
+     * @throws NullPointerException
+     *          If {@code pointer} is {@code null}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *             if this file is closed or another I/O error occurs.
+     */
+    public long read(Pointer pointer)
+        throws NullPointerException, IOException
+    {
+        if (pointer.isNull())
+            throw new NullPointerException();
+        return FileWrapper.read(fd, pointer, 0L, pointer.sizeof());
+    }
+
+    /**
+     * Reads at most {@code count} bytes from the current position in this file
+     * and stores them in the Pointer {@code pointer} starting at
+     * {@code offset}. Blocks until {@code count} bytes have been read,
+     * the end of the file is reached or an exception is thrown.
+     *
+     * @param pointer
+     *          The {code Pointer} in which to store the bytes read from
+     *          this file.
+     * @param offset
+     *          The initial position in {@code pointer} to store the bytes read
+     *          from this file.
+     * @param count
+     *          The maximum number of bytes to store in {@code pointer}.
+     *
+     * @return The number of bytes actually read or {@code -1} if the end of
+     *         the stream has been reached.
+     *
+     * @throws NullPointerException
+     *          If {@code pointer} is {@code null}.
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code buffer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long read(Pointer pointer, long offset, long count)
+        throws NullPointerException, IndexOutOfBoundsException, IOException
+    {
+        if (pointer.isNull())
+            throw new NullPointerException();
+        if (count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0L) {
+            /* Returning zero usually represents a timeout.
+             */
+            return 0L;
+        }
+        return FileWrapper.read(fd, pointer, offset, count);
+    }
+
+    /**
+     * Reads bytes from the current position in this file and stores them in the
+     * {@code buffer}. The maximum number of bytes read corresponds
+     * to the size of {@code buffer}. Blocks until at least one byte has been
+     * read if the file is in blocking mode.
+     *
+     * @param buffer
+     *            The {@code ByteBuffer} in which to store the bytes read.
+     * @return The number of bytes actually read or {@code -1} if the end of
+     *         the file has been reached.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *             if this file is closed or another I/O error occurs.
+     */
+    public int read(ByteBuffer buffer)
+        throws IOException
+    {
+        return FileWrapper.read(fd, buffer, 0, buffer.capacity());
+    }
+
+    /**
+     * Reads at most {@code count} bytes from the current position in this file
+     * and stores them in the ByteBuffer {@code buffer} starting at
+     * {@code offset}. Blocks until {@code count} bytes have been read,
+     * the end of the file is reached or an exception is thrown.
+     *
+     * @param buffer
+     *          The {code ByteBuffer} in which to store the bytes read from
+     *          this file.
+     * @param offset
+     *          The initial position in {@code buffer} to store the bytes read
+     *          from this file.
+     * @param count
+     *          The maximum number of bytes to store in {@code buffer}.
+     *
+     * @return The number of bytes actually read or {@code -1} if the end of
+     *         the stream has been reached.
+     *
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code buffer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int read(ByteBuffer buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (buffer.capacity() - offset) || count < 0 || offset < 0)
+            throw new IndexOutOfBoundsException();
+        if (count == 0) {
+            /* Returning zero usually represents a timeout.
+             */
+            return 0;
+        }
+        return FileWrapper.read(fd, buffer, offset, count);
+    }
+
+    /**
+     * Writes a byte to this file, starting at the current file pointer. Only
+     * the least significant byte of the integer {@code b} is written.
+     *
+     * @param b
+     *            the byte to write to this file.
+     *
+     * @return The number of bytes actually written.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int write(int b)
+        throws IOException
+    {
+        return FileWrapper.write(fd, b);
+    }
+
+    /**
+     * Writes the entire contents of the byte array {@code buffer} to this file,
+     * starting at the current file pointer.
+     *
+     * @param buffer
+     *            the buffer to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int write(byte[] buffer)
+        throws IOException
+    {
+        if (buffer.length == 0) {
+            return 0;
+        }
+        return FileWrapper.write(fd, buffer, 0, buffer.length);
+    }
+
+    /**
+     * Writes {@code count} bytes from the byte array {@code buffer} to this
+     * file, starting at the current file pointer and using {@code offset} as
+     * the first position within {@code buffer} to get bytes.
+     *
+     * @param buffer
+     *            The buffer to write to this file.
+     * @param offset
+     *            The index of the first byte in {@code buffer} to write.
+     * @param count
+     *            The number of bytes from {@code buffer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code buffer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int write(byte[] buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (buffer.length - offset) || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.write(fd, buffer, offset, count);
+    }
+
+    /**
+     * Writes the entire contents of the Pointer {@code pointer} to this file,
+     * starting at the current file pointer.
+     *
+     * @param pointer
+     *            the {@code Pointer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws NullPointerException
+     *          If {@code pointer} is {@code null}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long write(Pointer pointer)
+        throws NullPointerException, IOException
+    {
+        if (pointer.isNull())
+            throw new NullPointerException();
+        return FileWrapper.write(fd, pointer, 0L, pointer.sizeof());
+    }
+
+    /**
+     * Writes {@code count} bytes from the Pointer {@code pointer} to this
+     * file, starting at the current file pointer and using {@code offset} as
+     * the first position within {@code pointer} to get bytes.
+     *
+     * @param pointer
+     *            The {@code Pointer} to write to this file.
+     * @param offset
+     *            The index of the first byte in {@code pointer} to write.
+     * @param count
+     *            The number of bytes from {@code pointer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws NullPointerException
+     *          If {@code pointer} is {@code null}.
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code pointer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long write(Pointer pointer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (pointer.isNull())
+            throw new NullPointerException();
+        if (count < 0L || offset < 0L) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.write(fd, pointer, offset, count);
+    }
+
+    /**
+     * Writes the entire contents of the ByteBuffer {@code buffer} to this file,
+     * starting at the current file pointer.
+     *
+     * @param buffer
+     *            The {@code ByteBuffer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int write(ByteBuffer buffer)
+        throws IOException
+    {
+        return FileWrapper.write(fd, buffer, 0, buffer.capacity());
+    }
+
+    /**
+     * Writes {@code count} bytes from the ByteBuffer {@code buffer} to this
+     * file, starting at the current file pointer and using {@code offset} as
+     * the first position within {@code buffer} to get bytes.
+     *
+     * @param buffer
+     *            The {@code ByteBuffer} to write to this file.
+     * @param offset
+     *            The index of the first byte in {@code buffer} to write.
+     * @param count
+     *            The number of bytes from {@code buffer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code buffer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int write(ByteBuffer buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (buffer.capacity() - offset) || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.write(fd, buffer, offset, count);
+    }
+
+    /**
+     * Writes {@code count} arrays from the array of byte arrays {@code array}
+     * to this file, starting at the current file pointer and using
+     * {@code offset} as the first position within {@code array} to get bytes.
+     *
+     * @param array
+     *            The array of buffer arrays to write to this file.
+     * @param offset
+     *            The index of the first array in {@code array} to write.
+     * @param count
+     *            The number of arrays from {@code array} to write.
+     *
+     * @throws IndexOutOfBoundsException
+     *             if {@code count < 0}, {@code offset < 0} or
+     *             {@code count + offset} is greater than the size of
+     *             {@code array}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long write(byte[][] array, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (array.length - offset) || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.write(fd, array, offset, count);
+    }
+
+
+    /**
+     * Writes {@code count} arrays from the ByteBufferr {@code array}
+     * to this file, starting at the current file pointer and using
+     * {@code offset} as the first position within {@code array} to get bytes.
+     *
+     * @param array
+     *            The {@code ByteBuffer} array to write to this file.
+     * @param offset
+     *            The index of the first array in {@code array} to write.
+     * @param count
+     *            The number of arrays from {@code array} to write.
+     * @throws IndexOutOfBoundsException
+     *             if {@code count < 0}, {@code offset < 0} or
+     *             {@code count + offset} is greater than the size of
+     *             {@code array}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long write(ByteBuffer[] array, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (array.length - offset) || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.write(fd, array, offset, count);
+    }
+
+
+    /**
+     * Writes {@code count} bytes from the byte array {@code buffer} to this
+     * file, starting at the current file pointer and using {@code offset} as
+     * the first position within {@code buffer} to get bytes.
+     * <p>
+     * Method tries to fully write provided data blocking if necessary
+     * regardless of file blocking mode.
+     * </p>
+     *
+     * @param buffer
+     *            The buffer to write to this file.
+     * @param offset
+     *            The index of the first byte in {@code buffer} to write.
+     * @param count
+     *            The number of bytes from {@code buffer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws IndexOutOfBoundsException
+     *             if {@code count < 0}, {@code offset < 0} or
+     *             {@code count + offset} is greater than the size of
+     *             {@code array}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int writeFully(byte[] buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (buffer.length - offset) || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.writeFully(fd, buffer, offset, count);
+    }
+
+    /**
+     * Writes the entire contents of the ByteBuffer {@code buffer} to this file,
+     * starting at the current file pointer.
+     *
+     * @param buffer
+     *            the {@code ByteBuffer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int writeFully(ByteBuffer buffer)
+        throws IOException
+    {
+        return FileWrapper.write(fd, buffer, 0, buffer.capacity());
+    }
+
+    /**
+     * Writes {@code count} bytes from the ByteBuffer {@code buffer} to this
+     * file, starting at the current file pointer and using {@code offset} as
+     * the first position within {@code buffer} to get bytes.
+     * <p>
+     * Method tries to fully write provided data blocking if necessary
+     * regardless of file blocking mode.
+     * </p>
+     *
+     * @param buffer
+     *            The buffer to write to this file.
+     * @param offset
+     *            The index of the first byte in {@code buffer} to write.
+     * @param count
+     *            The number of bytes from {@code buffer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code buffer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public int writeFully(ByteBuffer buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (count > (buffer.capacity() - offset) || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.writeFully(fd, buffer, offset, count);
+    }
+
+
+    /**
+     * Writes the entire contents of the Pointer {@code pointer} to this file,
+     * starting at the current file pointer.
+     *
+     * @param pointer
+     *            the {@code Pointer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws NullPointerException
+     *          If {@code pointer} is {@code null}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long writeFully(Pointer pointer)
+        throws NullPointerException, IOException
+    {
+        if (pointer.isNull())
+            throw new NullPointerException();
+        return FileWrapper.write(fd, pointer, 0L, pointer.sizeof());
+    }
+
+    /**
+     * Writes {@code count} bytes from the Pointer {@code pointer} to this
+     * file, starting at the current file pointer and using {@code offset} as
+     * the first position within {@code buffer} to get bytes.
+     * <p>
+     * Method tries to fully write provided data blocking if necessary
+     * regardless of file blocking mode.
+     * </p>
+     *
+     * @param pointer
+     *            The {@code Pointer} to write to this file.
+     * @param offset
+     *            The index of the first byte in {@code pointer} to write.
+     * @param count
+     *            The number of bytes from {@code pointer} to write.
+     * @return The number of bytes actually written.
+     *
+     * @throws NullPointerException
+     *          If {@code pointer} is {@code null}.
+     * @throws IndexOutOfBoundsException
+     *          If {@code offset < 0} or {@code count < 0}, or if
+     *          {@code offset + count} is greater than the size of
+     *          {@code pointer}.
+     * @throws ClosedDescriptorException
+     *          If this file is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this file while the write
+     *             operation is in progress.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public long writeFully(Pointer pointer, long offset, long count)
+        throws NullPointerException, IndexOutOfBoundsException, IOException
+    {
+        if (pointer.isNull())
+            throw new NullPointerException();
+        if (count == 0) {
+            return 0;
+        }
+        return FileWrapper.writeFully(fd, pointer, offset, count);
+    }
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Stream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Stream.java?rev=825175&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Stream.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Stream.java Wed Oct 14 16:00:47 2009
@@ -0,0 +1,157 @@
+/*
+ * 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.runtime.io;
+
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.SyncFailedException;
+
+/**
+ * I/O Stream interface.
+ */
+public abstract class Stream implements Closeable, Flushable, Syncable
+{
+
+    /**
+     * Returns the number of bytes that are available before this stream will
+     * block.
+     *
+     * @return the number of bytes available before blocking.
+     * @throws IOException
+     *             if an error occurs in this stream.
+     */
+    public int available()
+        throws IOException
+    {
+        return 0;
+    }
+
+    /**
+     * Closes the object and release any system resources it holds. If the
+     * object has already been closed, then invoking this method has no effect.
+     *
+     * @throws IOException
+     *              if any error occurs when closing the object.
+     */
+    public abstract void close()
+        throws IOException;
+
+    /**
+     * Flush the underlying stream metadata.
+     * <p>
+     * {@code flush} transfers  all modified metadata of the stream object
+     * referred to by {@code this} stream to the disk device
+     * (or other storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    public abstract void flush()
+        throws SyncFailedException, IOException;
+
+    /**
+     * Sync the underlying stream by writing any buffered data.
+     * <p>
+     * {@code sync} transfers  all  modified in-core data of the stream object
+     * referred to by {@code this} stream to the disk device
+     * (or other storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    public abstract void sync()
+        throws SyncFailedException, IOException;
+
+    /**
+     * Test if {@code this} stream is valid.
+     *
+     * @return {@code true} if the stream represents a valid,
+     *         open file, socket, or other I/O object; {@code false} otherwse.
+     *
+     */
+    public abstract boolean valid();
+
+    /**
+     * Test wather or not every I/O operation on {@code this} stream will
+     * block until it completes.
+     *
+     * @return {@code true} if, and only if, this stream
+     *         is in blocking mode.
+     *
+     * @throws IOException if an I/O error occurs.
+     */
+    public boolean isBlocking()
+        throws IOException
+    {
+        return false;
+    }
+
+    /**
+     * Reads a single byte from the current position in this stream and returns
+     * it as an integer in the range from 0 to 255. Returns {@code -1} if the
+     * end of the file has been reached. Blocks until one byte has been read,
+     * the end of the file is detected or an exception is thrown.
+     *
+     * @return The byte read or {@code -1} if the end of the stream has
+     *         been reached.
+     * @throws ClosedDescriptorException
+     *          If this stream is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this stream while the read
+     *          operation is in progress.
+     * @throws TimeoutException
+     *          If read operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public abstract int read()
+        throws IOException;
+
+    /**
+     * Writes a byte to this stream, starting at the current file pointer. Only
+     * the least significant byte of the integer {@code b} is written.
+     *
+     * @param b
+     *            the byte to write to this stream.
+     *
+     * @return The number of bytes actually written.
+     *
+     * @throws ClosedDescriptorException
+     *          If this stream is closed.
+     * @throws AsyncClosedDescriptorException
+     *          If another thread closes this stream while the read
+     *             operation is in progress.
+     * @throws TimeoutException
+     *          If write operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public abstract int write(int b)
+        throws IOException;
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Stream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Syncable.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Syncable.java?rev=825175&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Syncable.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Syncable.java Wed Oct 14 16:00:47 2009
@@ -0,0 +1,48 @@
+/*
+ * 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.runtime.io;
+
+import java.io.IOException;
+import java.io.SyncFailedException;
+
+/**
+ * Defines an interface for classes that can (or need to) be synced, typically
+ * before some output processing is considered to be finished and the object
+ * gets closed.
+ * <p>
+ * Unilike {@link java.io.Flushable} interface {@code flush}, the {@code sync}
+ * is usually used for flushing object's metadata to the output device.
+ *
+ */
+public interface Syncable
+{
+
+    /**
+     * Ensures that data which is buffered within the underlying implementation
+     * is written out to the appropriate device before returning.
+     *
+     * @throws SyncFailedException
+     *              when the object cannot be flushed.
+     * @throws IOException
+     *              if an I/O error occurs.
+     */
+    public void sync()
+        throws SyncFailedException, IOException;
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Syncable.java
------------------------------------------------------------------------------
    svn:eol-style = native