jdk/src/share/classes/java/nio/channels/Channels.java
changeset 2057 3acf8e5e2ca0
parent 1637 bfa39b25f0fc
child 3631 4dc04372d56b
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
     1 /*
     1 /*
     2  * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
    31 import java.io.OutputStream;
    31 import java.io.OutputStream;
    32 import java.io.Reader;
    32 import java.io.Reader;
    33 import java.io.Writer;
    33 import java.io.Writer;
    34 import java.io.IOException;
    34 import java.io.IOException;
    35 import java.nio.ByteBuffer;
    35 import java.nio.ByteBuffer;
    36 import java.nio.CharBuffer;
       
    37 import java.nio.BufferOverflowException;
       
    38 import java.nio.BufferUnderflowException;
       
    39 import java.nio.charset.Charset;
    36 import java.nio.charset.Charset;
    40 import java.nio.charset.CharsetDecoder;
    37 import java.nio.charset.CharsetDecoder;
    41 import java.nio.charset.CharsetEncoder;
    38 import java.nio.charset.CharsetEncoder;
    42 import java.nio.charset.CoderResult;
       
    43 import java.nio.charset.UnsupportedCharsetException;
    39 import java.nio.charset.UnsupportedCharsetException;
    44 import java.nio.channels.spi.AbstractInterruptibleChannel;
    40 import java.nio.channels.spi.AbstractInterruptibleChannel;
       
    41 import java.util.concurrent.ExecutionException;
    45 import sun.nio.ch.ChannelInputStream;
    42 import sun.nio.ch.ChannelInputStream;
    46 import sun.nio.cs.StreamDecoder;
    43 import sun.nio.cs.StreamDecoder;
    47 import sun.nio.cs.StreamEncoder;
    44 import sun.nio.cs.StreamEncoder;
    48 
    45 
    49 
    46 
   180                 public void close() throws IOException {
   177                 public void close() throws IOException {
   181                     ch.close();
   178                     ch.close();
   182                 }
   179                 }
   183 
   180 
   184             };
   181             };
       
   182     }
       
   183 
       
   184     /**
       
   185      * {@note new}
       
   186      * Constructs a stream that reads bytes from the given channel.
       
   187      *
       
   188      * <p> The stream will not be buffered, and it will not support the {@link
       
   189      * InputStream#mark mark} or {@link InputStream#reset reset} methods.  The
       
   190      * stream will be safe for access by multiple concurrent threads.  Closing
       
   191      * the stream will in turn cause the channel to be closed.  </p>
       
   192      *
       
   193      * @param  ch
       
   194      *         The channel from which bytes will be read
       
   195      *
       
   196      * @return  A new input stream
       
   197      *
       
   198      * @since 1.7
       
   199      */
       
   200     public static InputStream newInputStream(final AsynchronousByteChannel ch) {
       
   201         checkNotNull(ch, "ch");
       
   202         return new InputStream() {
       
   203 
       
   204             private ByteBuffer bb = null;
       
   205             private byte[] bs = null;           // Invoker's previous array
       
   206             private byte[] b1 = null;
       
   207 
       
   208             @Override
       
   209             public synchronized int read() throws IOException {
       
   210                 if (b1 == null)
       
   211                     b1 = new byte[1];
       
   212                 int n = this.read(b1);
       
   213                 if (n == 1)
       
   214                     return b1[0] & 0xff;
       
   215                 return -1;
       
   216             }
       
   217 
       
   218             @Override
       
   219             public synchronized int read(byte[] bs, int off, int len)
       
   220                 throws IOException
       
   221             {
       
   222                 if ((off < 0) || (off > bs.length) || (len < 0) ||
       
   223                     ((off + len) > bs.length) || ((off + len) < 0)) {
       
   224                     throw new IndexOutOfBoundsException();
       
   225                 } else if (len == 0)
       
   226                     return 0;
       
   227 
       
   228                 ByteBuffer bb = ((this.bs == bs)
       
   229                                  ? this.bb
       
   230                                  : ByteBuffer.wrap(bs));
       
   231                 bb.position(off);
       
   232                 bb.limit(Math.min(off + len, bb.capacity()));
       
   233                 this.bb = bb;
       
   234                 this.bs = bs;
       
   235 
       
   236                 boolean interrupted = false;
       
   237                 try {
       
   238                     for (;;) {
       
   239                         try {
       
   240                             return ch.read(bb).get();
       
   241                         } catch (ExecutionException ee) {
       
   242                             throw new IOException(ee.getCause());
       
   243                         } catch (InterruptedException ie) {
       
   244                             interrupted = true;
       
   245                         }
       
   246                     }
       
   247                 } finally {
       
   248                     if (interrupted)
       
   249                         Thread.currentThread().interrupt();
       
   250                 }
       
   251             }
       
   252 
       
   253             @Override
       
   254             public void close() throws IOException {
       
   255                 ch.close();
       
   256             }
       
   257         };
       
   258     }
       
   259 
       
   260     /**
       
   261      * {@note new}
       
   262      * Constructs a stream that writes bytes to the given channel.
       
   263      *
       
   264      * <p> The stream will not be buffered. The stream will be safe for access
       
   265      * by multiple concurrent threads.  Closing the stream will in turn cause
       
   266      * the channel to be closed.  </p>
       
   267      *
       
   268      * @param  ch
       
   269      *         The channel to which bytes will be written
       
   270      *
       
   271      * @return  A new output stream
       
   272      *
       
   273      * @since 1.7
       
   274      */
       
   275     public static OutputStream newOutputStream(final AsynchronousByteChannel ch) {
       
   276         checkNotNull(ch, "ch");
       
   277         return new OutputStream() {
       
   278 
       
   279             private ByteBuffer bb = null;
       
   280             private byte[] bs = null;   // Invoker's previous array
       
   281             private byte[] b1 = null;
       
   282 
       
   283             @Override
       
   284             public synchronized void write(int b) throws IOException {
       
   285                if (b1 == null)
       
   286                     b1 = new byte[1];
       
   287                 b1[0] = (byte)b;
       
   288                 this.write(b1);
       
   289             }
       
   290 
       
   291             @Override
       
   292             public synchronized void write(byte[] bs, int off, int len)
       
   293                 throws IOException
       
   294             {
       
   295                 if ((off < 0) || (off > bs.length) || (len < 0) ||
       
   296                     ((off + len) > bs.length) || ((off + len) < 0)) {
       
   297                     throw new IndexOutOfBoundsException();
       
   298                 } else if (len == 0) {
       
   299                     return;
       
   300                 }
       
   301                 ByteBuffer bb = ((this.bs == bs)
       
   302                                  ? this.bb
       
   303                                  : ByteBuffer.wrap(bs));
       
   304                 bb.limit(Math.min(off + len, bb.capacity()));
       
   305                 bb.position(off);
       
   306                 this.bb = bb;
       
   307                 this.bs = bs;
       
   308 
       
   309                 boolean interrupted = false;
       
   310                 try {
       
   311                     while (bb.remaining() > 0) {
       
   312                         try {
       
   313                             ch.write(bb).get();
       
   314                         } catch (ExecutionException ee) {
       
   315                             throw new IOException(ee.getCause());
       
   316                         } catch (InterruptedException ie) {
       
   317                             interrupted = true;
       
   318                         }
       
   319                     }
       
   320                 } finally {
       
   321                     if (interrupted)
       
   322                         Thread.currentThread().interrupt();
       
   323                 }
       
   324             }
       
   325 
       
   326             @Override
       
   327             public void close() throws IOException {
       
   328                 ch.close();
       
   329             }
       
   330         };
   185     }
   331     }
   186 
   332 
   187 
   333 
   188     // -- Channels from streams --
   334     // -- Channels from streams --
   189 
   335 
   466                                    String csName)
   612                                    String csName)
   467     {
   613     {
   468         checkNotNull(csName, "csName");
   614         checkNotNull(csName, "csName");
   469         return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
   615         return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
   470     }
   616     }
   471 
       
   472 }
   617 }