Beispiel #1
0
    @Override
    public int read(byte[] bytes, int off, int len) throws IOException {
      if (bytes == null) {
        throw new NullPointerException("null destination buffer");
      }
      if ((len | off | (off + len) | (bytes.length - (off + len))) < 0) {
        throw new IndexOutOfBoundsException();
      }
      if (len == 0) {
        return 0;
      }

      try {
        synchronized (stream) {
          final int available = stream.bufferedInputBytesRemaining();
          if (available >= len) {
            return stream.copyBufferedBytes(bytes, off, len);
          } else if (stream.getDescriptor().getChannel() instanceof SelectableChannel) {
            SelectableChannel ch = (SelectableChannel) stream.getDescriptor().getChannel();
            synchronized (ch.blockingLock()) {
              boolean oldBlocking = ch.isBlocking();
              try {
                if (!oldBlocking) {
                  ch.configureBlocking(true);
                }
                return stream.bufferedRead(ByteBuffer.wrap(bytes, off, len), true);
              } finally {
                if (!oldBlocking) {
                  ch.configureBlocking(oldBlocking);
                }
              }
            }
          } else {
            return stream.bufferedRead(ByteBuffer.wrap(bytes, off, len), true);
          }
        }
      } catch (BadDescriptorException ex) {
        throw new IOException(ex.getMessage());
      } catch (EOFException ex) {
        return -1;
      }
    }
Beispiel #2
0
  /**
   * @deprecated readall do busy loop for the IO which has NONBLOCK bit. You should implement the
   *     logic by yourself with fread().
   */
  @Deprecated
  public synchronized ByteList readall() throws IOException, BadDescriptorException {
    final long fileSize =
        descriptor.isSeekable() && descriptor.getChannel() instanceof FileChannel
            ? ((FileChannel) descriptor.getChannel()).size()
            : 0;
    //
    // Check file size - special files in /proc have zero size and need to be
    // handled by the generic read path.
    //
    if (fileSize > 0) {
      ensureRead();

      FileChannel channel = (FileChannel) descriptor.getChannel();
      final long left = fileSize - channel.position() + bufferedInputBytesRemaining();
      if (left <= 0) {
        eof = true;
        return null;
      }

      if (left > Integer.MAX_VALUE) {
        if (getRuntime() != null) {
          throw getRuntime().newIOError("File too large");
        } else {
          throw new IOException("File too large");
        }
      }

      ByteList result = new ByteList((int) left);
      ByteBuffer buf = ByteBuffer.wrap(result.getUnsafeBytes(), result.begin(), (int) left);

      //
      // Copy any buffered data (including ungetc byte)
      //
      copyBufferedBytes(buf);

      //
      // Now read unbuffered directly from the file
      //
      while (buf.hasRemaining()) {
        final int MAX_READ_CHUNK = 1 * 1024 * 1024;
        //
        // When reading into a heap buffer, the jvm allocates a temporary
        // direct ByteBuffer of the requested size.  To avoid allocating
        // a huge direct buffer when doing ludicrous reads (e.g. 1G or more)
        // we split the read up into chunks of no more than 1M
        //
        ByteBuffer tmp = buf.duplicate();
        if (tmp.remaining() > MAX_READ_CHUNK) {
          tmp.limit(tmp.position() + MAX_READ_CHUNK);
        }
        int n = channel.read(tmp);
        if (n <= 0) {
          break;
        }
        buf.position(tmp.position());
      }
      eof = true;
      result.length(buf.position());
      return result;
    } else if (descriptor.isNull()) {
      return new ByteList(0);
    } else {
      checkReadable();

      ByteList byteList = new ByteList();
      ByteList read = fread(BUFSIZE);

      if (read == null) {
        eof = true;
        return byteList;
      }

      while (read != null) {
        byteList.append(read);
        read = fread(BUFSIZE);
      }

      return byteList;
    }
  }