NIO FileChannel Impl 분석

3203 단어 데이터 구조jni
fileChannle. write (ByteBuffer [] src) 밑바닥 을 호출 하 는 것 은 어떻게 이 루어 집 니까?순환 쓰기 인가요?Direct 와 No - Direct 는 어떤 구역 이 변 합 니까?다음은 소스 코드 를 결합 하여 설명 한다.
 
 
 
static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd) throws IOException {
		int nextWithRemaining = remaining(bufs);
		// if all bufs are empty we should return immediately
		if (nextWithRemaining < 0)
			return 0;
		// If some bufs are empty we should skip them
		if (nextWithRemaining > 0)
			bufs = skipBufs(bufs, nextWithRemaining);

		int numBufs = bufs.length;
		int bytesReadyToWrite = 0;

		// Create shadow to ensure DirectByteBuffers are used
		//         DirectBuffer     copy  ,             
		ByteBuffer[] shadow = new ByteBuffer[numBufs];
		for (int i = 0; i < numBufs; i++) {
			if (!(bufs[i] instanceof DirectBuffer)) {
				int pos = bufs[i].position();
				int lim = bufs[i].limit();
				assert (pos <= lim);
				int rem = (pos <= lim ? lim - pos : 0);

				ByteBuffer bb = ByteBuffer.allocateDirect(rem);
				shadow[i] = bb;
				// Leave slow buffer position untouched; it will be updated
				// after we see how many bytes were really written out
				bb.put(bufs[i]);
				bufs[i].position(pos);
				bb.flip();
			} else {
				shadow[i] = bufs[i];
			}
		}

		IOVecWrapper vec = null;
		long bytesWritten = 0;
		try {
			// Create a native iovec array
			vec = new IOVecWrapper(numBufs);

			// Fill in the iovec array with appropriate data
			//   DirectBuffer     IOVec    ,         writev   
			for (int i = 0; i < numBufs; i++) {
				ByteBuffer nextBuffer = shadow[i];
				// put in the buffer addresses
				long pos = nextBuffer.position();
				long len = nextBuffer.limit() - pos;
				bytesReadyToWrite += len;
				vec.putBase(i, ((DirectBuffer) nextBuffer).address() + pos);
				vec.putLen(i, len);
			}

			// Invoke native call to fill the buffers
			// jni    writev,          ,              
			bytesWritten = nd.writev(fd, vec.address, numBufs);
		} finally {
			vec.free();
		}
		long returnVal = bytesWritten;

		// Notify the buffers how many bytes were taken
		//         ,     ByteBuffers
		for (int i = 0; i < numBufs; i++) {
			ByteBuffer nextBuffer = bufs[i];
			int pos = nextBuffer.position();
			int lim = nextBuffer.limit();
			assert (pos <= lim);
			int len = (pos <= lim ? lim - pos : lim);
			if (bytesWritten >= len) {
				bytesWritten -= len;
				int newPosition = pos + len;
				nextBuffer.position(newPosition);
			} else { // Buffers not completely filled
				if (bytesWritten > 0) {
					assert (pos + bytesWritten < (long) Integer.MAX_VALUE);
					int newPosition = (int) (pos + bytesWritten);
					nextBuffer.position(newPosition);
				}
				break;
			}
		}
		return returnVal;
	}

좋은 웹페이지 즐겨찾기