1 7 8 package java.nio.channels; 9 10 import java.io.FileInputStream ; 11 import java.io.FileOutputStream ; 12 import java.io.InputStream ; 13 import java.io.OutputStream ; 14 import java.io.Reader ; 15 import java.io.Writer ; 16 import java.io.IOException ; 17 import java.nio.ByteBuffer ; 18 import java.nio.CharBuffer ; 19 import java.nio.BufferOverflowException ; 20 import java.nio.BufferUnderflowException ; 21 import java.nio.charset.Charset ; 22 import java.nio.charset.CharsetDecoder ; 23 import java.nio.charset.CharsetEncoder ; 24 import java.nio.charset.CoderResult ; 25 import java.nio.charset.UnsupportedCharsetException ; 26 import java.nio.channels.spi.AbstractInterruptibleChannel ; 27 import sun.nio.ch.ChannelInputStream; 28 import sun.nio.cs.StreamDecoder; 29 import sun.nio.cs.StreamEncoder; 30 31 32 46 47 public final class Channels { 48 49 private Channels() { } 51 52 private static int write(WritableByteChannel ch, ByteBuffer bb) 53 throws IOException 54 { 55 if (ch instanceof SelectableChannel ) { 56 SelectableChannel sc = (SelectableChannel )ch; 57 synchronized (sc.blockingLock()) { 58 if (!sc.isBlocking()) 59 throw new IllegalBlockingModeException (); 60 return ch.write(bb); 61 } 62 } else { 63 return ch.write(bb); 64 } 65 } 66 67 68 70 86 public static InputStream newInputStream(ReadableByteChannel ch) { 87 return new sun.nio.ch.ChannelInputStream(ch); 88 } 89 90 104 public static OutputStream newOutputStream(final WritableByteChannel ch) { 105 return new OutputStream () { 106 107 private ByteBuffer bb = null; 108 private byte[] bs = null; private byte[] b1 = null; 110 111 public synchronized void write(int b) throws IOException { 112 if (b1 == null) 113 b1 = new byte[1]; 114 b1[0] = (byte)b; 115 this.write(b1); 116 } 117 118 public synchronized void write(byte[] bs, int off, int len) 119 throws IOException 120 { 121 if ((off < 0) || (off > bs.length) || (len < 0) || 122 ((off + len) > bs.length) || ((off + len) < 0)) { 123 throw new IndexOutOfBoundsException (); 124 } else if (len == 0) { 125 return; 126 } 127 ByteBuffer bb = ((this.bs == bs) 128 ? this.bb 129 : ByteBuffer.wrap(bs)); 130 bb.limit(Math.min(off + len, bb.capacity())); 131 bb.position(off); 132 this.bb = bb; 133 this.bs = bs; 134 Channels.write(ch, bb); 135 } 136 137 public void close() throws IOException { 138 ch.close(); 139 } 140 141 }; 142 } 143 144 145 147 159 public static ReadableByteChannel newChannel(final InputStream in) { 160 if (in instanceof FileInputStream ) { 161 String inClass = in.getClass().toString(); 162 if (inClass.equals("java.io.FileInputStream")) 163 return ((FileInputStream )in).getChannel(); 164 } 165 return new ReadableByteChannelImpl(in); 166 } 167 168 private static class ReadableByteChannelImpl 169 extends AbstractInterruptibleChannel implements ReadableByteChannel 171 { 172 InputStream in; 173 private static final int TRANSFER_SIZE = 8192; 174 private byte buf[] = new byte[0]; 175 private boolean open = true; 176 private Object readLock = new Object (); 177 178 ReadableByteChannelImpl(InputStream in) { 179 this.in = in; 180 } 181 182 public int read(ByteBuffer dst) throws IOException { 183 int len = dst.remaining(); 184 int totalRead = 0; 185 int bytesRead = 0; 186 synchronized (readLock) { 187 while (totalRead < len) { 188 int bytesToRead = Math.min((len - totalRead), 189 TRANSFER_SIZE); 190 if (buf.length < bytesToRead) 191 buf = new byte[bytesToRead]; 192 if ((totalRead > 0) && !(in.available() > 0)) 193 break; try { 195 begin(); 196 bytesRead = in.read(buf, 0, bytesToRead); 197 } finally { 198 end(bytesRead > 0); 199 } 200 if (bytesRead < 0) 201 break; 202 else 203 totalRead += bytesRead; 204 dst.put(buf, 0, bytesRead); 205 } 206 if ((bytesRead < 0) && (totalRead == 0)) 207 return -1; 208 209 return totalRead; 210 } 211 } 212 213 protected void implCloseChannel() throws IOException { 214 in.close(); 215 open = false; 216 } 217 } 218 219 220 232 public static WritableByteChannel newChannel(final OutputStream out) { 233 if (out instanceof FileOutputStream ) { 234 String outClass = out.getClass().toString(); 235 if (outClass.equals("java.io.FileOutputStream")) 236 return ((FileOutputStream )out).getChannel(); 237 } 238 return new WritableByteChannelImpl(out); 239 } 240 241 private static class WritableByteChannelImpl 242 extends AbstractInterruptibleChannel implements WritableByteChannel 244 { 245 OutputStream out; 246 private static final int TRANSFER_SIZE = 8192; 247 private byte buf[] = new byte[0]; 248 private boolean open = true; 249 private Object writeLock = new Object (); 250 251 WritableByteChannelImpl(OutputStream out) { 252 this.out = out; 253 } 254 255 public int write(ByteBuffer src) throws IOException { 256 int len = src.remaining(); 257 int totalWritten = 0; 258 synchronized (writeLock) { 259 while (totalWritten < len) { 260 int bytesToWrite = Math.min((len - totalWritten), 261 TRANSFER_SIZE); 262 if (buf.length < bytesToWrite) 263 buf = new byte[bytesToWrite]; 264 src.get(buf, 0, bytesToWrite); 265 try { 266 begin(); 267 out.write(buf, 0, bytesToWrite); 268 } finally { 269 end(bytesToWrite > 0); 270 } 271 totalWritten += bytesToWrite; 272 } 273 return totalWritten; 274 } 275 } 276 277 protected void implCloseChannel() throws IOException { 278 out.close(); 279 open = false; 280 } 281 } 282 283 284 286 312 public static Reader newReader(ReadableByteChannel ch, 313 CharsetDecoder dec, 314 int minBufferCap) 315 { 316 dec.reset(); 317 return StreamDecoder.forDecoder(ch, dec, minBufferCap); 318 } 319 320 349 public static Reader newReader(ReadableByteChannel ch, 350 String csName) 351 { 352 return newReader(ch, Charset.forName(csName).newDecoder(), -1); 353 } 354 355 380 public static Writer newWriter(final WritableByteChannel ch, 381 final CharsetEncoder enc, 382 final int minBufferCap) 383 { 384 enc.reset(); 385 return StreamEncoder.forEncoder(ch, enc, minBufferCap); 386 } 387 388 417 public static Writer newWriter(WritableByteChannel ch, 418 String csName) 419 { 420 return newWriter(ch, Charset.forName(csName).newEncoder(), -1); 421 } 422 423 } 424 | Popular Tags |