mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8066678: java.nio.channels.Channels cleanup
Reviewed-by: alanb, chegar
This commit is contained in:
parent
7e7e10eb42
commit
421fc583be
1 changed files with 103 additions and 108 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -38,6 +38,7 @@ import java.nio.charset.CharsetDecoder;
|
||||||
import java.nio.charset.CharsetEncoder;
|
import java.nio.charset.CharsetEncoder;
|
||||||
import java.nio.charset.UnsupportedCharsetException;
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.nio.channels.spi.AbstractInterruptibleChannel;
|
import java.nio.channels.spi.AbstractInterruptibleChannel;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import sun.nio.ch.ChannelInputStream;
|
import sun.nio.ch.ChannelInputStream;
|
||||||
import sun.nio.cs.StreamDecoder;
|
import sun.nio.cs.StreamDecoder;
|
||||||
|
@ -48,8 +49,8 @@ import sun.nio.cs.StreamEncoder;
|
||||||
* Utility methods for channels and streams.
|
* Utility methods for channels and streams.
|
||||||
*
|
*
|
||||||
* <p> This class defines static methods that support the interoperation of the
|
* <p> This class defines static methods that support the interoperation of the
|
||||||
* stream classes of the <tt>{@link java.io}</tt> package with the channel
|
* stream classes of the {@link java.io} package with the channel classes
|
||||||
* classes of this package. </p>
|
* of this package. </p>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author Mark Reinhold
|
* @author Mark Reinhold
|
||||||
|
@ -60,12 +61,7 @@ import sun.nio.cs.StreamEncoder;
|
||||||
|
|
||||||
public final class Channels {
|
public final class Channels {
|
||||||
|
|
||||||
private Channels() { } // No instantiation
|
private Channels() { throw new Error("no instances"); }
|
||||||
|
|
||||||
private static void checkNotNull(Object o, String name) {
|
|
||||||
if (o == null)
|
|
||||||
throw new NullPointerException("\"" + name + "\" is null!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write all remaining bytes in buffer to the given channel.
|
* Write all remaining bytes in buffer to the given channel.
|
||||||
|
@ -107,7 +103,7 @@ public final class Channels {
|
||||||
/**
|
/**
|
||||||
* Constructs a stream that reads bytes from the given channel.
|
* Constructs a stream that reads bytes from the given channel.
|
||||||
*
|
*
|
||||||
* <p> The <tt>read</tt> methods of the resulting stream will throw an
|
* <p> The {@code read} methods of the resulting stream will throw an
|
||||||
* {@link IllegalBlockingModeException} if invoked while the underlying
|
* {@link IllegalBlockingModeException} if invoked while the underlying
|
||||||
* channel is in non-blocking mode. The stream will not be buffered, and
|
* channel is in non-blocking mode. The stream will not be buffered, and
|
||||||
* it will not support the {@link InputStream#mark mark} or {@link
|
* it will not support the {@link InputStream#mark mark} or {@link
|
||||||
|
@ -121,14 +117,14 @@ public final class Channels {
|
||||||
* @return A new input stream
|
* @return A new input stream
|
||||||
*/
|
*/
|
||||||
public static InputStream newInputStream(ReadableByteChannel ch) {
|
public static InputStream newInputStream(ReadableByteChannel ch) {
|
||||||
checkNotNull(ch, "ch");
|
Objects.requireNonNull(ch, "ch");
|
||||||
return new sun.nio.ch.ChannelInputStream(ch);
|
return new ChannelInputStream(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a stream that writes bytes to the given channel.
|
* Constructs a stream that writes bytes to the given channel.
|
||||||
*
|
*
|
||||||
* <p> The <tt>write</tt> methods of the resulting stream will throw an
|
* <p> The {@code write} methods of the resulting stream will throw an
|
||||||
* {@link IllegalBlockingModeException} if invoked while the underlying
|
* {@link IllegalBlockingModeException} if invoked while the underlying
|
||||||
* channel is in non-blocking mode. The stream will not be buffered. The
|
* channel is in non-blocking mode. The stream will not be buffered. The
|
||||||
* stream will be safe for access by multiple concurrent threads. Closing
|
* stream will be safe for access by multiple concurrent threads. Closing
|
||||||
|
@ -139,15 +135,16 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @return A new output stream
|
* @return A new output stream
|
||||||
*/
|
*/
|
||||||
public static OutputStream newOutputStream(final WritableByteChannel ch) {
|
public static OutputStream newOutputStream(WritableByteChannel ch) {
|
||||||
checkNotNull(ch, "ch");
|
Objects.requireNonNull(ch, "ch");
|
||||||
|
|
||||||
return new OutputStream() {
|
return new OutputStream() {
|
||||||
|
|
||||||
private ByteBuffer bb = null;
|
private ByteBuffer bb;
|
||||||
private byte[] bs = null; // Invoker's previous array
|
private byte[] bs; // Invoker's previous array
|
||||||
private byte[] b1 = null;
|
private byte[] b1;
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void write(int b) throws IOException {
|
public synchronized void write(int b) throws IOException {
|
||||||
if (b1 == null)
|
if (b1 == null)
|
||||||
b1 = new byte[1];
|
b1 = new byte[1];
|
||||||
|
@ -155,6 +152,7 @@ public final class Channels {
|
||||||
this.write(b1);
|
this.write(b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void write(byte[] bs, int off, int len)
|
public synchronized void write(byte[] bs, int off, int len)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
@ -174,6 +172,7 @@ public final class Channels {
|
||||||
Channels.writeFully(ch, bb);
|
Channels.writeFully(ch, bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
ch.close();
|
ch.close();
|
||||||
}
|
}
|
||||||
|
@ -196,13 +195,13 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @since 1.7
|
* @since 1.7
|
||||||
*/
|
*/
|
||||||
public static InputStream newInputStream(final AsynchronousByteChannel ch) {
|
public static InputStream newInputStream(AsynchronousByteChannel ch) {
|
||||||
checkNotNull(ch, "ch");
|
Objects.requireNonNull(ch, "ch");
|
||||||
return new InputStream() {
|
return new InputStream() {
|
||||||
|
|
||||||
private ByteBuffer bb = null;
|
private ByteBuffer bb;
|
||||||
private byte[] bs = null; // Invoker's previous array
|
private byte[] bs; // Invoker's previous array
|
||||||
private byte[] b1 = null;
|
private byte[] b1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized int read() throws IOException {
|
public synchronized int read() throws IOException {
|
||||||
|
@ -221,8 +220,9 @@ public final class Channels {
|
||||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
||||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
((off + len) > bs.length) || ((off + len) < 0)) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
} else if (len == 0)
|
} else if (len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ByteBuffer bb = ((this.bs == bs)
|
ByteBuffer bb = ((this.bs == bs)
|
||||||
? this.bb
|
? this.bb
|
||||||
|
@ -270,13 +270,13 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @since 1.7
|
* @since 1.7
|
||||||
*/
|
*/
|
||||||
public static OutputStream newOutputStream(final AsynchronousByteChannel ch) {
|
public static OutputStream newOutputStream(AsynchronousByteChannel ch) {
|
||||||
checkNotNull(ch, "ch");
|
Objects.requireNonNull(ch, "ch");
|
||||||
return new OutputStream() {
|
return new OutputStream() {
|
||||||
|
|
||||||
private ByteBuffer bb = null;
|
private ByteBuffer bb;
|
||||||
private byte[] bs = null; // Invoker's previous array
|
private byte[] bs; // Invoker's previous array
|
||||||
private byte[] b1 = null;
|
private byte[] b1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void write(int b) throws IOException {
|
public synchronized void write(int b) throws IOException {
|
||||||
|
@ -343,11 +343,10 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @return A new readable byte channel
|
* @return A new readable byte channel
|
||||||
*/
|
*/
|
||||||
public static ReadableByteChannel newChannel(final InputStream in) {
|
public static ReadableByteChannel newChannel(InputStream in) {
|
||||||
checkNotNull(in, "in");
|
Objects.requireNonNull(in, "in");
|
||||||
|
|
||||||
if (in instanceof FileInputStream &&
|
if (in.getClass() == FileInputStream.class) {
|
||||||
FileInputStream.class.equals(in.getClass())) {
|
|
||||||
return ((FileInputStream) in).getChannel();
|
return ((FileInputStream) in).getChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,16 +357,16 @@ public final class Channels {
|
||||||
extends AbstractInterruptibleChannel // Not really interruptible
|
extends AbstractInterruptibleChannel // Not really interruptible
|
||||||
implements ReadableByteChannel
|
implements ReadableByteChannel
|
||||||
{
|
{
|
||||||
InputStream in;
|
private final InputStream in;
|
||||||
private static final int TRANSFER_SIZE = 8192;
|
private static final int TRANSFER_SIZE = 8192;
|
||||||
private byte buf[] = new byte[0];
|
private byte[] buf = new byte[0];
|
||||||
private boolean open = true;
|
private final Object readLock = new Object();
|
||||||
private Object readLock = new Object();
|
|
||||||
|
|
||||||
ReadableByteChannelImpl(InputStream in) {
|
ReadableByteChannelImpl(InputStream in) {
|
||||||
this.in = in;
|
this.in = in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int read(ByteBuffer dst) throws IOException {
|
public int read(ByteBuffer dst) throws IOException {
|
||||||
int len = dst.remaining();
|
int len = dst.remaining();
|
||||||
int totalRead = 0;
|
int totalRead = 0;
|
||||||
|
@ -399,9 +398,9 @@ public final class Channels {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void implCloseChannel() throws IOException {
|
protected void implCloseChannel() throws IOException {
|
||||||
in.close();
|
in.close();
|
||||||
open = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,11 +417,10 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @return A new writable byte channel
|
* @return A new writable byte channel
|
||||||
*/
|
*/
|
||||||
public static WritableByteChannel newChannel(final OutputStream out) {
|
public static WritableByteChannel newChannel(OutputStream out) {
|
||||||
checkNotNull(out, "out");
|
Objects.requireNonNull(out, "out");
|
||||||
|
|
||||||
if (out instanceof FileOutputStream &&
|
if (out.getClass() == FileOutputStream.class) {
|
||||||
FileOutputStream.class.equals(out.getClass())) {
|
|
||||||
return ((FileOutputStream) out).getChannel();
|
return ((FileOutputStream) out).getChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,16 +431,16 @@ public final class Channels {
|
||||||
extends AbstractInterruptibleChannel // Not really interruptible
|
extends AbstractInterruptibleChannel // Not really interruptible
|
||||||
implements WritableByteChannel
|
implements WritableByteChannel
|
||||||
{
|
{
|
||||||
OutputStream out;
|
private final OutputStream out;
|
||||||
private static final int TRANSFER_SIZE = 8192;
|
private static final int TRANSFER_SIZE = 8192;
|
||||||
private byte buf[] = new byte[0];
|
private byte[] buf = new byte[0];
|
||||||
private boolean open = true;
|
private final Object writeLock = new Object();
|
||||||
private Object writeLock = new Object();
|
|
||||||
|
|
||||||
WritableByteChannelImpl(OutputStream out) {
|
WritableByteChannelImpl(OutputStream out) {
|
||||||
this.out = out;
|
this.out = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int write(ByteBuffer src) throws IOException {
|
public int write(ByteBuffer src) throws IOException {
|
||||||
int len = src.remaining();
|
int len = src.remaining();
|
||||||
int totalWritten = 0;
|
int totalWritten = 0;
|
||||||
|
@ -465,9 +463,9 @@ public final class Channels {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void implCloseChannel() throws IOException {
|
protected void implCloseChannel() throws IOException {
|
||||||
out.close();
|
out.close();
|
||||||
open = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +477,7 @@ public final class Channels {
|
||||||
* given decoder.
|
* given decoder.
|
||||||
*
|
*
|
||||||
* <p> The resulting stream will contain an internal input buffer of at
|
* <p> The resulting stream will contain an internal input buffer of at
|
||||||
* least <tt>minBufferCap</tt> bytes. The stream's <tt>read</tt> methods
|
* least {@code minBufferCap} bytes. The stream's {@code read} methods
|
||||||
* will, as needed, fill the buffer by reading bytes from the underlying
|
* will, as needed, fill the buffer by reading bytes from the underlying
|
||||||
* channel; if the channel is in non-blocking mode when bytes are to be
|
* channel; if the channel is in non-blocking mode when bytes are to be
|
||||||
* read then an {@link IllegalBlockingModeException} will be thrown. The
|
* read then an {@link IllegalBlockingModeException} will be thrown. The
|
||||||
|
@ -495,7 +493,7 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @param minBufferCap
|
* @param minBufferCap
|
||||||
* The minimum capacity of the internal byte buffer,
|
* The minimum capacity of the internal byte buffer,
|
||||||
* or <tt>-1</tt> if an implementation-dependent
|
* or {@code -1} if an implementation-dependent
|
||||||
* default capacity is to be used
|
* default capacity is to be used
|
||||||
*
|
*
|
||||||
* @return A new reader
|
* @return A new reader
|
||||||
|
@ -504,7 +502,7 @@ public final class Channels {
|
||||||
CharsetDecoder dec,
|
CharsetDecoder dec,
|
||||||
int minBufferCap)
|
int minBufferCap)
|
||||||
{
|
{
|
||||||
checkNotNull(ch, "ch");
|
Objects.requireNonNull(ch, "ch");
|
||||||
return StreamDecoder.forDecoder(ch, dec.reset(), minBufferCap);
|
return StreamDecoder.forDecoder(ch, dec.reset(), minBufferCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,16 +512,15 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* <p> An invocation of this method of the form
|
* <p> An invocation of this method of the form
|
||||||
*
|
*
|
||||||
* <blockquote><pre>
|
* <pre> {@code
|
||||||
* Channels.newReader(ch, csname)</pre></blockquote>
|
* Channels.newReader(ch, csname)
|
||||||
|
* } </pre>
|
||||||
*
|
*
|
||||||
* behaves in exactly the same way as the expression
|
* behaves in exactly the same way as the expression
|
||||||
*
|
*
|
||||||
* <blockquote><pre>
|
* <pre> {@code
|
||||||
* Channels.newReader(ch,
|
* Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
|
||||||
* Charset.forName(csName)
|
* } </pre>
|
||||||
* .newDecoder(),
|
|
||||||
* -1);</pre></blockquote>
|
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* The channel from which bytes will be read
|
* The channel from which bytes will be read
|
||||||
|
@ -540,7 +537,7 @@ public final class Channels {
|
||||||
public static Reader newReader(ReadableByteChannel ch,
|
public static Reader newReader(ReadableByteChannel ch,
|
||||||
String csName)
|
String csName)
|
||||||
{
|
{
|
||||||
checkNotNull(csName, "csName");
|
Objects.requireNonNull(csName, "csName");
|
||||||
return newReader(ch, Charset.forName(csName).newDecoder(), -1);
|
return newReader(ch, Charset.forName(csName).newDecoder(), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,7 +546,7 @@ public final class Channels {
|
||||||
* writes the resulting bytes to the given channel.
|
* writes the resulting bytes to the given channel.
|
||||||
*
|
*
|
||||||
* <p> The resulting stream will contain an internal output buffer of at
|
* <p> The resulting stream will contain an internal output buffer of at
|
||||||
* least <tt>minBufferCap</tt> bytes. The stream's <tt>write</tt> methods
|
* least {@code minBufferCap} bytes. The stream's {@code write} methods
|
||||||
* will, as needed, flush the buffer by writing bytes to the underlying
|
* will, as needed, flush the buffer by writing bytes to the underlying
|
||||||
* channel; if the channel is in non-blocking mode when bytes are to be
|
* channel; if the channel is in non-blocking mode when bytes are to be
|
||||||
* written then an {@link IllegalBlockingModeException} will be thrown.
|
* written then an {@link IllegalBlockingModeException} will be thrown.
|
||||||
|
@ -564,16 +561,16 @@ public final class Channels {
|
||||||
*
|
*
|
||||||
* @param minBufferCap
|
* @param minBufferCap
|
||||||
* The minimum capacity of the internal byte buffer,
|
* The minimum capacity of the internal byte buffer,
|
||||||
* or <tt>-1</tt> if an implementation-dependent
|
* or {@code -1} if an implementation-dependent
|
||||||
* default capacity is to be used
|
* default capacity is to be used
|
||||||
*
|
*
|
||||||
* @return A new writer
|
* @return A new writer
|
||||||
*/
|
*/
|
||||||
public static Writer newWriter(final WritableByteChannel ch,
|
public static Writer newWriter(WritableByteChannel ch,
|
||||||
final CharsetEncoder enc,
|
CharsetEncoder enc,
|
||||||
final int minBufferCap)
|
int minBufferCap)
|
||||||
{
|
{
|
||||||
checkNotNull(ch, "ch");
|
Objects.requireNonNull(ch, "ch");
|
||||||
return StreamEncoder.forEncoder(ch, enc.reset(), minBufferCap);
|
return StreamEncoder.forEncoder(ch, enc.reset(), minBufferCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,17 +579,15 @@ public final class Channels {
|
||||||
* charset and writes the resulting bytes to the given channel.
|
* charset and writes the resulting bytes to the given channel.
|
||||||
*
|
*
|
||||||
* <p> An invocation of this method of the form
|
* <p> An invocation of this method of the form
|
||||||
*
|
* <p>
|
||||||
* <blockquote><pre>
|
* <pre> {@code
|
||||||
* Channels.newWriter(ch, csname)</pre></blockquote>
|
* Channels.newWriter(ch, csname)
|
||||||
*
|
* } </pre>
|
||||||
* behaves in exactly the same way as the expression
|
* behaves in exactly the same way as the expression
|
||||||
*
|
* <p>
|
||||||
* <blockquote><pre>
|
* <pre> {@code
|
||||||
* Channels.newWriter(ch,
|
* Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
|
||||||
* Charset.forName(csName)
|
* } </pre>
|
||||||
* .newEncoder(),
|
|
||||||
* -1);</pre></blockquote>
|
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* The channel to which bytes will be written
|
* The channel to which bytes will be written
|
||||||
|
@ -609,7 +604,7 @@ public final class Channels {
|
||||||
public static Writer newWriter(WritableByteChannel ch,
|
public static Writer newWriter(WritableByteChannel ch,
|
||||||
String csName)
|
String csName)
|
||||||
{
|
{
|
||||||
checkNotNull(csName, "csName");
|
Objects.requireNonNull(csName, "csName");
|
||||||
return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
|
return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue