- Interface Channel
- Method Summary
- Method Details
- isOpen
- close
- java.nio.channels.ClosedChannelException
- 2 Answers 2
- Java NIO Channel Tutorial
- 1.1. Opening a Channel
- Example 1: How to get a FileChannel
- Example 2: How to create a SocketChannel
- 1.2. Using the Channels
- Example 3: We cannot write to a read-only file using any channel
- Example 4: Copying data from one channel to another channel in Java
- 1.3. Closing a Channel
Interface Channel
A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
A channel is either open or closed. A channel is open upon creation, and once closed it remains closed. Once a channel is closed, any attempt to invoke an I/O operation upon it will cause a ClosedChannelException to be thrown. Whether or not a channel is open may be tested by invoking its isOpen method.
Channels are, in general, intended to be safe for multithreaded access as described in the specifications of the interfaces and classes that extend and implement this interface.
Method Summary
Method Details
isOpen
close
Closes this channel. After a channel is closed, any further attempt to invoke I/O operations upon it will cause a ClosedChannelException to be thrown. If this channel is already closed then invoking this method has no effect. This method may be invoked at any time. If some other thread has already invoked it, however, then another invocation will block until the first invocation is complete, after which it will return without effect.
Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples. Other versions.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2023, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.
java.nio.channels.ClosedChannelException
How can i solve this problem. I got following error: java.nio.channels.ClosedChannelException This is coding:
public void run() < try < SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(512); int i1 = socketChannel.read(buffer); if (buffer.limit() == 0 || i1 == -1) < Socket s = null; try < s = socketChannel.socket(); s.close(); key.cancel(); >catch (IOException ie) < if (UnitDataServer.isLog) < log.error("Error closing socket " + s + ": " + ie); >> > else < buffer.flip(); if (UnitDataServer.isLog) < log.info(" Recvd Message from Unit : " + buffer.array()); >byte byteArray[] = buffer.array(); log.info("Byte Array length :" + byteArray.length); hexString = new StringBuffer(); for (int i = 0; i < i1 /* byteArray.length */; i++) < String hex = Integer.toHexString(0xFF & byteArray[i]); if (hex.length() == 1) < // could use a for loop, but we're only dealing with a // single byte hexString.append('0'); >hexString.append(hex); > hexString.trimToSize(); log.info("Hex String :" + hexString); Communicator.dataReceive(new DataReceive( socketChannel, hexString.toString(), dst)); > > catch (Exception e) < if (UnitDataServer.isLog) < // log.error(e); >try < socketChannel.socket().close(); key.cancel(); >catch (IOException ex) < if (UnitDataServer.isLog) < log.error(ex); >> > >
We need some more information on the source code that caused the error and the exact stack trace.
need more info, preferably code examples that shows the exceptions thrown. Here is the javadoc page, if that helps: java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/…
2 Answers 2
You have closed the channel and are still trying to use it.
There are several issues with your code.
First, your test for EOS is faulty. Remove the limit() == 0 test. That doesn’t indicate EOS, it just indicates a zero length read, which can happen in non-blocking mode at any time. It doesn’t mean the peer has closed his end of the connection, and it doesn’t mean you should close your end.
Second, closing a channel closes the socket as well. You should close the channel only, not the socket.
Third, closing a channel cancels the key. You don’t need to follow every close with a cancel.
You may also have failed to check whether a ready key is valid in the select loop before using it, e.g. for reading.
I continue to be amazed, and amused, and bemused, by the claim elsewhere in this thread that ‘source code is untrue’ under some circumstances.
Java NIO Channel Tutorial
Channels are the second major addition to java.nio after buffers which we have learned in my previous tutorial in detail. Channels provide direct connection to the I/O services.
A Channel is a medium that transports data efficiently between byte buffers and the entity on the other end of the channel (usually a file or socket).
Usually, channels have a one-to-one relationship with operating-system file descriptors. The Channel classes provide the abstraction needed to maintain platform independence but still model the native I/O capabilities of modern operating systems.
Channels are gateways through which the native I/O services of the operating system can be accessed with a minimum of overhead, and buffers are the internal endpoints used by channels to send and receive data.
At the top of hirarchy, there is Channel interface which looks like this:
package java.nio.channels; public interface Channel
Channel implementations vary radically between operating systems due to various factors that depend on the underlying platform, so the channel APIs (or interfaces) simply describe what can be done.
Channel implementations often use native code to perform actual work. In this way, the channel interfaces allow you to gain access to low-level I/O services in a controlled and portable way.
As you can see by the top-level Channel interface, there are only two operations common to all channels: checking to see if a channel is open ( isOpen() ) and closing an open channel ( close() ).
1.1. Opening a Channel
As we already know that I/O falls into two broad categories:
So it’s no surprise that there are two types of channels: file and socket. FileChannel class and SocketChannel classes are used to deal with these two categories.
FileChannel object can be obtained only by calling the getChannel() method on an open RandomAccessFile , FileInputStream , or FileOutputStream object. You cannot create a FileChannel object directly.
Example 1: How to get a FileChannel
RandomAccessFile raf = new RandomAccessFile ("somefile", "r"); FileChannel fc = raf.getChannel();
Opposite to FileChannel , socket channels have factory methods to create new socket channels directly.
Example 2: How to create a SocketChannel
//How to open SocketChannel SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("somehost", someport)); //How to open ServerSocketChannel ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind (new InetSocketAddress (somelocalport)); //How to open DatagramChannel DatagramChannel dc = DatagramChannel.open();
The above methods return a corresponding socket channel object. They are not sources of new channels as RandomAccessFile.getChannel() is. They return the channel associated with a socket if one already exists; they never create new channels.
1.2. Using the Channels
As we already learned into buffers tutorial that channels transfer data to and from ByteBuffer objects. Most of the read/write operations are performed by methods implemented from below interfaces.
public interface ReadableByteChannel extends Channel < public int read (ByteBuffer dst) throws IOException; >public interface WritableByteChannel extends Channel < public int write (ByteBuffer src) throws IOException; >public interface ByteChannel extends ReadableByteChannel, WritableByteChannel
Channels can be unidirectional or bidirectional.
A given channel class might implement ReadableByteChannel , which defines the read() method. Another might implement WritableByteChannel to provide write() .
A class implementing one or the other of these interfaces is unidirectional: it can transfer data in only one direction. If a class implements both interfaces (or ByteChannel which extends both interfaces), it is bidirectional and can transfer data in both directions.
If you go through Channel classes, you’ll find that each of the file and socket channels implement all three of these interfaces. In terms of class definition, this means that all the file and socket channel objects are bidirectional.
This is not a problem for sockets because they’re always bidirectional, but it is an issue for files. A FileChannel object obtained from the getChannel() method of a FileInputStream object is read-only but is bidirectional in terms of interface declarations because FileChannel implements ByteChannel .
Invoking write() on such a channel will throw the unchecked NonWritableChannelException because FileInputStream always opens files with read-only permission. So remember that when a channel connects to a specific I/O service, the capabilities of a channel instance will be constrained by the characteristics of the service to which it’s connected.
A Channel instance connected to a read-only file cannot write, even though the class to which that channel instance belongs may have a write() method. It falls to the programmer to know how the channel was opened and not to attempt an operation the underlying I/O service won’t allow.
Example 3: We cannot write to a read-only file using any channel
FileInputStream input = new FileInputStream ("readOnlyFile.txt"); FileChannel channel = input.getChannel(); // This will compile but will throw an IOException // because the underlying file is read-only channel.write (buffer);
The read() and write() methods of ByteChannel take ByteBuffer objects as arguments. Each returns the number of bytes transferred, which can be less than the number of bytes in the buffer, or even zero. The position of the buffer will have been advanced by the same amount.
If a partial transfer was performed, the buffer can be resubmitted to the channel to continue transferring data where it left off. Repeat until the buffer’s hasRemaining() method returns false.
In the below example, we are copying data from one channel to another channel (or from one file to another file).
Example 4: Copying data from one channel to another channel in Java
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; public class ChannelCopyExample < public static void main(String args[]) throws IOException < FileInputStream input = new FileInputStream ("testIn.txt"); ReadableByteChannel source = input.getChannel(); FileOutputStream output = new FileOutputStream ("testOut.txt"); WritableByteChannel dest = output.getChannel(); copyData(source, dest); source.close(); dest.close(); >private static void copyData(ReadableByteChannel src, WritableByteChannel dest) throws IOException < ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024); while (src.read(buffer) != -1) < // Prepare the buffer to be drained buffer.flip(); // Make sure that the buffer was fully drained while (buffer.hasRemaining()) < dest.write(buffer); >// Make the buffer empty, ready for filling buffer.clear(); > > >
Channels can operate in blocking or non-blocking modes. A channel in non-blocking mode never puts the invoking thread to sleep. The requested operation either completes immediately or returns a result indicating that nothing was done. Only stream-oriented channels, such as sockets and pipes, can be placed in non-blocking mode.
1.3. Closing a Channel
To close a channel, use it’s close() method. Unlike buffers, channels cannot be reused after closing it. An open channel represents a specific connection to a specific I/O service and encapsulates the state of that connection. When a channel is closed, that connection is lost, and the channel is no longer connected to anything.
It’s harmless to call close() on a channel multiple times. Subsequent calls to close() on the closed channel do nothing and return immediately.
Socket channels could conceivably take a significant amount of time to close depending on the system’s networking implementation. Some network protocol stacks may block a close while the output is drained.
The open state of a channel can be tested with the isOpen() method. If it returns true, the channel can be used. If false, the channel has been closed and can no longer be used.
Attempting to read, write, or perform any other operation that requires the channel to be in an open state will result in a ClosedChannelException .