📄 nioutil.java
字号:
* avoiding thread context switches and selector registration business * as much as possible!!! This approach strongly improves throughput at * the expense of somewhat increased latency. */ int minIters = 2; // for efficiency iterate more than once int startPos = buffer.position(); int nr = 0; while ((minIters > 0 || nr > 0) && buffer.hasRemaining() && (nr = channel.read(buffer)) >= 0) { if (minIters > 0) minIters--; // safely avoid underflows } int total = buffer.position() - startPos; if (nr < 0) { // Reached end-of-stream, e.g. because remote host closed or lost connection total = -(total + 1); } return total; } /** * Efficiently writes (without ever blocking) as many bytes as possible from * the given buffer to the given non-blocking channel. Returns the total * number of bytes that have been written. The algorithm strongly improves * throughput at the expense of somewhat increased latency. This method * simply propagates exceptions thrown in the underlying * {@link WritableByteChannel#write(ByteBuffer)}NIO code - it never causes * an exception itself. * * @param channel - * the channel to write to * @param buffer - * the buffer to read from * @return the total number of bytes written, possibly zero. * * @throws NonWritableChannelException * If this channel was not opened for writing * * @throws ClosedChannelException * If this channel is closed * * @throws AsynchronousCloseException * If another thread closes this channel while the write * operation is in progress * * @throws ClosedByInterruptException * If another thread interrupts the current thread while the * write operation is in progress, thereby closing the channel * and setting the current thread's interrupt status * * @throws IOException * If some other I/O error occurs */ public static int writeMany(WritableByteChannel channel, ByteBuffer buffer) throws IOException { int minIters = 2; // for efficiency iterate more than once int startPos = buffer.position(); int nr = 0; while ((minIters > 0 || nr > 0) && buffer.hasRemaining()) { nr = channel.write(buffer); if (minIters > 0) minIters--; // safely avoid underflows } int total = buffer.position() - startPos; return total; } /** * Returns all selectable channels registered with the given selector, * excluding channels of invalid keys. * * @param selector * @return the channels */ public static List getRegisteredChannels(Selector selector) { // TODO: return as array, set, hashset? List channels = new ArrayList(); Iterator iter = selector.keys().iterator(); while (iter.hasNext()) { SelectionKey key = (SelectionKey) iter.next(); if (key.isValid()) { channels.add(key.channel()); } } return channels; } /** * Returns the number of ready operations of the given selection key. * * @param key * @return the number */ public static int getNumberOfReadyOps(SelectionKey key) { return bitCount(key.readyOps()); /* int n = 0; if (key.isAcceptable()) n++; if (key.isReadable()) n++; if (key.isWritable()) n++; if (key.isConnectable()) n++; return n; */ } /** * Returns the number of one-bits in the two's complement binary * representation of the specified <tt>int</tt> value. This function is * sometimes referred to as the <i>population count </i>. * * @param i the value to count on. * @return the number of one-bits in the two's complement binary * representation of the specified <tt>int</tt> value. */ private static int bitCount(int i) { // very efficient magic // HD, Figure 5-2 i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; } /** * Adds the given operation bits to the interest set of the given key. * * @param key * the selection key to work on. * @param opBits * the bits to add. */ public static void addInterestBits(SelectionKey key, int opBits) { int ops = key.interestOps(); if ((ops | opBits) != ops) key.interestOps(ops | opBits); } /** * Removes the given operation bits from the interest set of the given key. * * @param key * the selection key to work on. * @param opBits * the bits to remove. */ public static void removeInterestBits(SelectionKey key, int opBits) { int ops = key.interestOps(); if ((ops & ~opBits) != ops) key.interestOps(ops & ~opBits); } /** * Returns a detailed string representation of the given selection key for * debugging purposes. * * @param key * the object to represent * @return a string representation */ public static String toString(SelectionKey key) { String str = key.isValid() ? "Valid key [" : "INVALID key ["; if (key.isValid()) { // check avoids exceptions! str = str + "readyOps=" + toString(key.readyOps()); str = str + ", interestedOps=" + toString(key.interestOps()); str = str + ", "; } if (!(key.attachment() instanceof ArrayByteList)) { str = str + "attachment=" + key.attachment(); } str = str + ", channel=" + key.channel(); return str + "]"; } /** * Returns a detailed string representation of the given selection key * readyOps or interestOps for debugging purposes. * * @param selectionKeyOps * the object to represent * @return a string representation */ public static String toString(int selectionKeyOps) { String str = "{"; final String[] names = { "OP_READ", "OP_WRITE", "OP_CONNECT", "OP_ACCEPT"}; final int[] values = { SelectionKey.OP_READ, SelectionKey.OP_WRITE, SelectionKey.OP_CONNECT, SelectionKey.OP_ACCEPT}; boolean first = true; for (int i=0; i < values.length; i++) { if ((selectionKeyOps & values[i]) != 0) { if (! first) str = str + "|"; str = str + names[i]; first = false; } } return str + "}"; } /** * Returns a detailed string representation for debugging purposes. * * @param keySet * a selector key set (e.g. selector.keys() or * selector.selectedKeys()). * @return a string representation */ public static String toString(Set keySet) { if (keySet == null) return "[]"; List list = new ArrayList(keySet.size()); Iterator iter = keySet.iterator(); while (iter.hasNext()) { list.add(toString((SelectionKey) iter.next())); } return list.toString(); } /** * Returns a detailed string representation of the given selector for * debugging purposes. * * @param selector * the object to represent * @return a string representation */ public static String toString(Selector selector) { StringBuffer str = new StringBuffer(); str.append(selector.getClass().getName()).append(" {"); str.append("isOpen=").append(selector.isOpen()).append(","); if (selector.isOpen()) { str.append("\nValid registered channels=").append(getRegisteredChannels(selector)); str.append("\nInterestSet=").append(toString(selector.keys())); str.append("\nReadySet=").append(toString(selector.selectedKeys())); } str.append("}"); return str.toString(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -