/** * {@inheritDoc} */ @Override public void write(WritableByteChannel channel) throws IOException { logger.config(getLoggingFilename() + ":Writing tag to channel"); byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray(); logger.config(getLoggingFilename() + ":bodybytebuffer:sizebeforeunsynchronisation:" + bodyByteBuffer.length); //Unsynchronize if option enabled and unsync required unsynchronization = TagOptionSingleton.getInstance().isUnsyncTags() && ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer); if (isUnsynchronization()) { bodyByteBuffer = ID3Unsynchronization.unsynchronize(bodyByteBuffer); logger.config(getLoggingFilename() + ":bodybytebuffer:sizeafterunsynchronisation:" + bodyByteBuffer.length); } ByteBuffer headerBuffer = writeHeaderToBuffer(0, bodyByteBuffer.length); channel.write(headerBuffer); channel.write(ByteBuffer.wrap(bodyByteBuffer)); }
/** * copy * * @param src * @param dest * @throws IOException */ public static void fastCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException { final ByteBuffer buffer = ByteBuffer.allocateDirect(8 * 1024); int count = 0; while ((count = src.read(buffer)) != -1) { // LogUtil.d("luaviewp-fastCopy", count, buffer.capacity(), buffer.remaining(), buffer.array().length); // prepare the buffer to be drained buffer.flip(); // write to the channel, may block dest.write(buffer); // If partial transfer, shift remainder down // If buffer is empty, same as doing clear() buffer.compact(); } // EOF will leave buffer in fill state buffer.flip(); // make sure the buffer is fully drained. while (buffer.hasRemaining()) { dest.write(buffer); } }
/** * send a reply-acknowledgement (6,2,3), sends it doing a busy write, the ACK is so small * that it should always go to the buffer * @param key * @param channel */ protected void sendAck(SelectionKey key, WritableByteChannel channel, byte[] command, SocketAddress udpaddr) { try { ByteBuffer buf = ByteBuffer.wrap(command); int total = 0; if (channel instanceof DatagramChannel) { DatagramChannel dchannel = (DatagramChannel)channel; //were using a shared channel, document says its thread safe //TODO check optimization, one channel per thread? while ( total < command.length ) { total += dchannel.send(buf, udpaddr); } } else { while ( total < command.length ) { total += channel.write(buf); } } if (log.isTraceEnabled()) { log.trace("ACK sent to " + ( (channel instanceof SocketChannel) ? ((SocketChannel)channel).socket().getInetAddress() : ((DatagramChannel)channel).socket().getInetAddress())); } } catch ( java.io.IOException x ) { log.warn("Unable to send ACK back through channel, channel disconnected?: "+x.getMessage()); } }
/** * 将流转换为字符串 * * @param is * @return * @throws IOException */ public static String readStreamAsStr(InputStream is) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); WritableByteChannel dest = Channels.newChannel(bos); ReadableByteChannel src = Channels.newChannel(is); ByteBuffer bb = ByteBuffer.allocate(4096); while (src.read(bb) != -1) { bb.flip(); dest.write(bb); bb.clear(); } src.close(); dest.close(); return new String(bos.toByteArray(), Constants.ENCODING); }
/** * Constructs an adapter for the specified channel, output, and byte order. * If not null, the writable byte channel enables more efficient writes. * @param channel the writable byte channel; null, if none. * @param output the data output. * @param order the byte order. */ public ArrayOutputAdapter( WritableByteChannel channel, DataOutput output, ByteOrder order) { _wbc = channel; _do = output; _bo = order; if (_wbc!=null) { _bb = ByteBuffer.allocateDirect(4096); } else { _buffer = new byte[4096]; _bb = ByteBuffer.wrap(_buffer); } if (order==ByteOrder.BIG_ENDIAN) { _bb.order(ByteOrder.BIG_ENDIAN); } else { _bb.order(ByteOrder.LITTLE_ENDIAN); } _cb = _bb.asCharBuffer(); _sb = _bb.asShortBuffer(); _ib = _bb.asIntBuffer(); _lb = _bb.asLongBuffer(); _fb = _bb.asFloatBuffer(); _db = _bb.asDoubleBuffer(); }
/** * execute. * @param cmd - cmd * @throws IOException - IOException */ @Override public void execute(Command cmd) throws IOException { Path filePath = Paths.get(cmd.getParam()); if (Files.exists(filePath, LinkOption.NOFOLLOW_LINKS) && !Files.isDirectory(filePath) && Files.isReadable(filePath)) { System.out.println("Uploading..."); ObjectOutputStream oos = new ObjectOutputStream(outputStream); oos.writeObject(cmd); oos.flush(); WritableByteChannel rbc = Channels.newChannel(new DataOutputStream(outputStream)); FileInputStream fis = new FileInputStream(cmd.getParam()); fis.getChannel().transferTo(0, Long.MAX_VALUE, rbc); rbc.close(); System.out.println("Done."); } else { System.out.println("Error. Please try again."); } }
/** * send a reply-acknowledgement (6,2,3), sends it doing a busy write, the * ACK is so small that it should always go to the buffer * * @param key * @param channel */ protected void sendAck(SelectionKey key, WritableByteChannel channel, byte[] command, SocketAddress udpaddr) { try { ByteBuffer buf = ByteBuffer.wrap(command); int total = 0; if (channel instanceof DatagramChannel) { DatagramChannel dchannel = (DatagramChannel) channel; // were using a shared channel, document says its thread safe // TODO check optimization, one channel per thread? while (total < command.length) { total += dchannel.send(buf, udpaddr); } } else { while (total < command.length) { total += channel.write(buf); } } if (log.isTraceEnabled()) { log.trace("ACK sent to " + ((channel instanceof SocketChannel) ? ((SocketChannel) channel).socket().getInetAddress() : ((DatagramChannel) channel).socket().getInetAddress())); } } catch (java.io.IOException x) { log.warn("Unable to send ACK back through channel, channel disconnected?: " + x.getMessage()); } }
/** * @see Channels#newOutputStream(java.nio.channels.WritableByteChannel) */ public OutputStream getContentOutputStream() throws ContentIOException { try { WritableByteChannel channel = getWritableChannel(); OutputStream is = new BufferedOutputStream(Channels.newOutputStream(channel)); // done return is; } catch (Throwable e) { throw new ContentIOException("Failed to open stream onto channel: \n" + " writer: " + this, e); } }
@Override public long transferTo(WritableByteChannel target, long position) throws IOException { if (this.byteBufferHeader.hasRemaining()) { transferred += target.write(this.byteBufferHeader); return transferred; } else { List<ByteBuffer> messageBufferList = this.queryMessageResult.getMessageBufferList(); for (ByteBuffer bb : messageBufferList) { if (bb.hasRemaining()) { transferred += target.write(bb); return transferred; } } } return 0; }
public void getBox(WritableByteChannel os) throws IOException { ByteBuffer bb = ByteBuffer.allocate(l2i(getSize())); getHeader(bb); if (content == null) { getContent(bb); if (deadBytes != null) { deadBytes.rewind(); while (deadBytes.remaining() > 0) { bb.put(deadBytes); } } } else { content.rewind(); bb.put(content); } bb.rewind(); os.write(bb); }
/** * Gets a part of the given URL, writes the content into the given channel. * Fails if the returned HTTP status is not "206 partial content". * * @param <IWC> a generic type for any class that implements InterruptibleChannel and WritableByteChannel * @param url to get * @param output written with the content of the HTTP response * @param etag value of the If-Range header * @param range_start range byte start (inclusive) * @param range_end range byte end (inclusive) * * @return a response (contains the HTTP Headers, the status code, ...) * * @throws IOException IO error * @throws InterruptedException interrupted * @throws RuntimeException containing the actual exception if it is not an instance of IOException */ public <IWC extends InterruptibleChannel & WritableByteChannel> HttpResponse interruptibleGetRange(String url, final IWC output, String etag, long range_start, long range_end) throws IOException, InterruptedException { HttpGet get = new HttpGet(url); get.setHeader("If-Range", etag); get.setHeader("Range", String.format("bytes=%d-%d", range_start, range_end)); // This validator throws an IOException if the response code is not 206 partial content ResponseValidator val = new ResponseValidator() { @Override public void validate(HttpResponse response) throws HttpException, IOException { if (response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT) { throw new IOException("Range request does not return partial content"); } } }; return interruptibleRequest(get, output, val); }
public void getBox(WritableByteChannel writableByteChannel) throws IOException { ByteBuffer bb = ByteBuffer.allocate(16); long size = getSize(); if (isSmallBox(size)) { IsoTypeWriter.writeUInt32(bb, size); } else { IsoTypeWriter.writeUInt32(bb, 1); } bb.put(IsoFile.fourCCtoBytes("mdat")); if (isSmallBox(size)) { bb.put(new byte[8]); } else { IsoTypeWriter.writeUInt64(bb, size); } bb.rewind(); writableByteChannel.write(bb); }
@Override public long transferTo(WritableByteChannel target, long position) throws IOException { if (this.byteBufferHeader.hasRemaining()) { transfered += target.write(this.byteBufferHeader); return transfered; } else { List<ByteBuffer> messageBufferList = this.queryMessageResult.getMessageBufferList(); for (ByteBuffer bb : messageBufferList) { if (bb.hasRemaining()) { transfered += target.write(bb); return transfered; } } } return 0; }
/** * This code is more complicated than you would think because we might require multiple * transferTo invocations in order to transfer a single MessageWithHeader to avoid busy waiting. * * The contract is that the caller will ensure position is properly set to the total number * of bytes transferred so far (i.e. value returned by transfered()). */ @Override public long transferTo(final WritableByteChannel target, final long position) throws IOException { Preconditions.checkArgument(position == totalBytesTransferred, "Invalid position."); // Bytes written for header in this call. long writtenHeader = 0; if (header.readableBytes() > 0) { writtenHeader = copyByteBuf(header, target); totalBytesTransferred += writtenHeader; if (header.readableBytes() > 0) { return writtenHeader; } } // Bytes written for body in this call. long writtenBody = 0; if (body instanceof FileRegion) { writtenBody = ((FileRegion) body).transferTo(target, totalBytesTransferred - headerLength); } else if (body instanceof ByteBuf) { writtenBody = copyByteBuf((ByteBuf) body, target); } totalBytesTransferred += writtenBody; return writtenHeader + writtenBody; }
@Override public long transferTo(WritableByteChannel target, long position) throws IOException { if (manageOsCache && readaheadPool != null) { readaheadRequest = readaheadPool.readaheadStream(identifier, fd, getPosition() + position, readaheadLength, getPosition() + getCount(), readaheadRequest); } if(this.shuffleTransferToAllowed) { return super.transferTo(target, position); } else { return customShuffleTransfer(target, position); } }
private long transferToArbitraryChannel(long position, int icount, WritableByteChannel target) throws IOException { // Untrusted target: Use a newly-erased buffer int c = Math.min(icount, TRANSFER_SIZE); ByteBuffer bb = Util.getTemporaryDirectBuffer(c); long tw = 0; // Total bytes written long pos = position; try { Util.erase(bb); while (tw < icount) { bb.limit(Math.min((int)(icount - tw), TRANSFER_SIZE)); int nr = read(bb, pos); if (nr <= 0) break; bb.flip(); // ## Bug: Will block writing target if this channel // ## is asynchronously closed int nw = target.write(bb); tw += nw; if (nw != nr) break; pos += nw; bb.clear(); } return tw; } catch (IOException x) { if (tw > 0) return tw; throw x; } finally { Util.releaseTemporaryDirectBuffer(bb); } }
@Override public <R> R applyToChannel(Function<WritableByteChannel, R> f) throws IOException { if (strictFlushing) throw new UnsupportedOperationException(); //Don't allow writes to the underlying channel while data is buffered flush(); return f.apply(channel); }
private long transferToDirectlyInternal(long position, int icount, WritableByteChannel target, FileDescriptor targetFD) throws IOException { assert !nd.transferToDirectlyNeedsPositionLock() || Thread.holdsLock(positionLock); long n = -1; int ti = -1; try { begin(); ti = threads.add(); if (!isOpen()) return -1; do { n = transferTo0(fd, position, icount, targetFD); } while ((n == IOStatus.INTERRUPTED) && isOpen()); if (n == IOStatus.UNSUPPORTED_CASE) { if (target instanceof SinkChannelImpl) pipeSupported = false; if (target instanceof FileChannelImpl) fileSupported = false; return IOStatus.UNSUPPORTED_CASE; } if (n == IOStatus.UNSUPPORTED) { // Don't bother trying again transferSupported = false; return IOStatus.UNSUPPORTED; } return IOStatus.normalize(n); } finally { threads.remove(ti); end (n > -1); } }
/** * This is a wrapper around {@link WritableByteChannel#write(ByteBuffer)}. * If the amount of data is large, it writes to channel in smaller chunks. * This is to avoid jdk from creating many direct buffers as the size of * buffer increases. This also minimizes extra copies in NIO layer * as a result of multiple write operations required to write a large * buffer. * * @see WritableByteChannel#write(ByteBuffer) */ private int channelWrite(WritableByteChannel channel, ByteBuffer buffer) throws IOException { int count = (buffer.remaining() <= NIO_BUFFER_LIMIT) ? channel.write(buffer) : channelIO(null, channel, buffer); if (count > 0) { rpcMetrics.incrSentBytes(count); } return count; }
public long transferTo(long position, long count, WritableByteChannel target) throws IOException { ensureOpen(); if (!target.isOpen()) throw new ClosedChannelException(); if (!readable) throw new NonReadableChannelException(); if (target instanceof FileChannelImpl && !((FileChannelImpl)target).writable) throw new NonWritableChannelException(); if ((position < 0) || (count < 0)) throw new IllegalArgumentException(); long sz = size(); if (position > sz) return 0; int icount = (int)Math.min(count, Integer.MAX_VALUE); if ((sz - position) < icount) icount = (int)(sz - position); long n; // Attempt a direct transfer, if the kernel supports it if ((n = transferToDirectly(position, icount, target)) >= 0) return n; // Attempt a mapped transfer, but only to trusted channel types if ((n = transferToTrustedChannel(position, icount, target)) >= 0) return n; // Slow path for untrusted targets return transferToArbitraryChannel(position, icount, target); }
@Override public int send(WritableByteChannel channel, int sendCurrentLength) throws IOException { // The minimum of buffer, required package size and data available int n; synchronized (buffer) { long lag=nRead-nSent; if(lag>sendBuffer.capacity()) { // Overflow error, close this sender. n=0; }else { n=Math.min(sendCurrentLength, sendBuffer.capacity()-sendBuffer.position()); n=Math.min(n, getAvailable()); sendBuffer.limit(sendBuffer.position()+n); n=channel.write(sendBuffer); } } if(n>0) { nSent+=n; } if(sendBuffer.position()==sendBuffer.capacity()) { // We have reached the end of the send buffer. Next time start with the beginning. sendBuffer.clear(); } if(closedAt>-1 && nSent>=closedAt) { close(new EOFException()); } return n; }
private GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException { if (major > 4) { throw new IllegalArgumentException(); } if (major == 4 && minor > 0) { throw new IllegalArgumentException(); } this.versionMajor = major; this.versionMinor = minor; this.constantPool = new ConstantPool(); this.buffer = ByteBuffer.allocateDirect(256 * 1024); this.channel = channel; writeVersion(); }
@Override public WritableByteChannel getWritableChannel() throws ContentIOException { WritableByteChannel result = delegatee.getWritableChannel(); if (null == releaseableResource) { releaseableResource = result; } return result; }
@Override public long transferTo(WritableByteChannel target, long position) throws IOException { if (this.byteBufferHeader.hasRemaining()) { transferred += target.write(this.byteBufferHeader); return transferred; } else if (this.selectMappedBufferResult.getByteBuffer().hasRemaining()) { transferred += target.write(this.selectMappedBufferResult.getByteBuffer()); return transferred; } return 0; }
@Override public ChromiumUrlRequest createRequest(String url, int requestPriority, Map<String, String> headers, WritableByteChannel channel, HttpUrlRequestListener listener) { return new ChromiumUrlRequest( mRequestContext, url, requestPriority, headers, channel, listener); }
/** * {@inheritDoc} */ @Override public void write(WritableByteChannel channel, int currentTagSize) throws IOException { logger.config(getLoggingFilename() + ":Writing tag to channel"); byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray(); logger.config(getLoggingFilename() + ":bodybytebuffer:sizebeforeunsynchronisation:" + bodyByteBuffer.length); //Unsynchronize if option enabled and unsync required unsynchronization = TagOptionSingleton.getInstance().isUnsyncTags() && ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer); if (isUnsynchronization()) { bodyByteBuffer = ID3Unsynchronization.unsynchronize(bodyByteBuffer); logger.config(getLoggingFilename() + ":bodybytebuffer:sizeafterunsynchronisation:" + bodyByteBuffer.length); } int padding = 0; if(currentTagSize > 0) { int sizeIncPadding = calculateTagSize(bodyByteBuffer.length + TAG_HEADER_LENGTH, (int) currentTagSize); padding = sizeIncPadding - (bodyByteBuffer.length + TAG_HEADER_LENGTH); } ByteBuffer headerBuffer = writeHeaderToBuffer(padding, bodyByteBuffer.length); channel.write(headerBuffer); channel.write(ByteBuffer.wrap(bodyByteBuffer)); writePadding(channel, padding); }
/** * Helper for {@link #channelRead(java.nio.channels.ReadableByteChannel, java.nio.ByteBuffer)} * and {@link #channelWrite(GatheringByteChannel, BufferChain)}. Only * one of readCh or writeCh should be non-null. * * @param readCh read channel * @param writeCh write channel * @param buf buffer to read or write into/out of * @return bytes written * @throws java.io.IOException e * @see #channelRead(java.nio.channels.ReadableByteChannel, java.nio.ByteBuffer) * @see #channelWrite(GatheringByteChannel, BufferChain) */ private static int channelIO(ReadableByteChannel readCh, WritableByteChannel writeCh, ByteBuffer buf) throws IOException { int originalLimit = buf.limit(); int initialRemaining = buf.remaining(); int ret = 0; while (buf.remaining() > 0) { try { int ioSize = Math.min(buf.remaining(), NIO_BUFFER_LIMIT); buf.limit(buf.position() + ioSize); ret = (readCh == null) ? writeCh.write(buf) : readCh.read(buf); if (ret < ioSize) { break; } } finally { buf.limit(originalLimit); } } int nBytes = initialRemaining - buf.remaining(); return (nBytes > 0) ? nBytes : ret; }
@Override public long transferTo(WritableByteChannel target, long position) throws IOException { if (this.byteBufferHeader.hasRemaining()) { transfered += target.write(this.byteBufferHeader); return transfered; } else if (this.selectMappedBufferResult.getByteBuffer().hasRemaining()) { transfered += target.write(this.selectMappedBufferResult.getByteBuffer()); return transfered; } return 0; }
@Override public long transferTo(WritableByteChannel target, long position) throws IOException { if (this.byteBufferHeader.hasRemaining()) { transfered += target.write(this.byteBufferHeader); return transfered; } else if (this.selectMapedBufferResult.getByteBuffer().hasRemaining()) { transfered += target.write(this.selectMapedBufferResult.getByteBuffer()); return transfered; } return 0; }
public void getBox(WritableByteChannel os) throws IOException { for (Box replacer : replacers) { replacer.getBox(os); } ByteBuffer header = ByteBuffer.allocate(8); IsoTypeWriter.writeUInt32(header, 8 + data.limit()); header.put(TYPE.getBytes()); header.rewind(); os.write(header); data.rewind(); os.write(data); }
@Test public void testSimple() throws IOException { ByteBuffer buffer = createChunk(); StreamBuffer streamBuffer = new StreamBuffer(9); ByteArrayOutputStream bos = new ByteArrayOutputStream(); WritableByteChannel channel = Channels.newChannel(bos); streamBuffer.readFrom(buffer); streamBuffer.writeTo(channel); byte[] result = bos.toByteArray(); Assert.assertArrayEquals(buffer.array(), result); }
public static void writeFully(final WritableByteChannel channel, final ByteBuffer buf) throws IOException { do { int written = channel.write(buf); if (written < 0) { throw new EOFException(); } } while (buf.hasRemaining()); }
@Test public void testDatagramBoundaries() throws IOException { DatagramBuffer datagramBuffer = new DatagramBuffer(32); ByteArrayOutputStream bos = new ByteArrayOutputStream(); WritableByteChannel channel = Channels.newChannel(bos); ByteBuffer datagram5 = createDatagram(5); ByteBuffer datagram0 = createDatagram(0); ByteBuffer datagram3 = createDatagram(3); ByteBuffer datagram4 = createDatagram(4); datagramBuffer.readFrom(datagram5); datagramBuffer.readFrom(datagram0); datagramBuffer.readFrom(datagram3); datagramBuffer.readFrom(datagram4); datagramBuffer.writeTo(channel); byte[] result = bos.toByteArray(); Assert.assertArrayEquals(datagram5.array(), result); bos.reset(); datagramBuffer.writeTo(channel); result = bos.toByteArray(); Assert.assertArrayEquals(datagram0.array(), result); bos.reset(); datagramBuffer.writeTo(channel); result = bos.toByteArray(); Assert.assertArrayEquals(datagram3.array(), result); bos.reset(); datagramBuffer.writeTo(channel); result = bos.toByteArray(); Assert.assertArrayEquals(datagram4.array(), result); }
public void getBox(WritableByteChannel writableByteChannel) throws IOException { if (fileChannel != null) { assert checkStillOk(); transfer(fileChannel, startPosition - header.limit(), contentSize + header.limit(), writableByteChannel); } else { header.rewind(); writableByteChannel.write(header); writableByteChannel.write(content); } }
protected final void writeChildBoxes(ByteBuffer bb) { WritableByteChannel wbc = new ByteBufferByteChannel(bb); for (Box box : boxes) { try { box.getBox(wbc); } catch (IOException e) { // cannot happen since my WritableByteChannel won't throw any excpetion throw new RuntimeException("Cannot happen.", e); } } }
protected final void writeChildBoxes(ByteBuffer bb) { WritableByteChannel wbc = new ByteBufferByteChannel(bb); for (Box box : boxes) { try { box.getBox(wbc); } catch (IOException e) { // My WritableByteChannel won't throw any excpetion throw new RuntimeException("Cannot happen to me", e); } } }
public void getBox(WritableByteChannel writableByteChannel) throws IOException { ByteBuffer bb = ByteBuffer.allocate(16); long size = getSize(); if (isSmallBox(size)) { IsoTypeWriter.writeUInt32(bb, size); } else { IsoTypeWriter.writeUInt32(bb, 1); } bb.put(IsoFile.fourCCtoBytes("mdat")); if (isSmallBox(size)) { bb.put(new byte[8]); } else { IsoTypeWriter.writeUInt64(bb, size); } bb.rewind(); writableByteChannel.write(bb); if (writableByteChannel instanceof GatheringByteChannel) { List<ByteBuffer> nuSamples = unifyAdjacentBuffers(samples); for (int i = 0; i < Math.ceil((double) nuSamples.size() / STEPSIZE); i++) { List<ByteBuffer> sublist = nuSamples.subList( i * STEPSIZE, // start (i + 1) * STEPSIZE < nuSamples.size() ? (i + 1) * STEPSIZE : nuSamples.size()); // end ByteBuffer sampleArray[] = sublist.toArray(new ByteBuffer[sublist.size()]); do { ((GatheringByteChannel) writableByteChannel).write(sampleArray); } while (sampleArray[sampleArray.length - 1].remaining() > 0); } //System.err.println(bytesWritten); } else { for (ByteBuffer sample : samples) { sample.rewind(); writableByteChannel.write(sample); } } }