1. 기본 개념
IO는 메인 메모리 및 외부 장치 (하드 디스크, 터미널, 네트워크 등)별로 데이터를 복사하는 프로세스입니다. IO는 운영 체제의 기본 기능 구현이며 I/O 지침을 통해 완료됩니다.
모든 언어 런타임 시스템은 I/O를 수행하기위한 고급 도구를 제공합니다. (C의 PrintfScanf, Java의 객체 지향 캡슐화)
2. Java Standard IO의 검토
Java Standard IO 클래스 라이브러리는 IO 객체 지향의 추상화입니다. 로컬 방법의 기본 구현을 기반으로, 우리는 기본 구현에주의를 기울일 필요가 없습니다. 입력 스트림/outputStream : 한 번에 하나의 바이트를 전송합니다. 독자/작가 : 한 번에 한 캐릭터.
3. 소개
NIO는 JDK1.4에 제공된 새로운 API 인 Javanewio의 약어입니다. Sun이 공식적으로 주장하는 특성은 다음과 같습니다.
모든 원시 유형에 대한 (버퍼) 캐시 지원을 제공합니다.
문자 세트 인코딩 및 디코딩 솔루션.
채널 : 새로운 원본 I/O 추상화.
잠금 및 메모리 매핑 파일의 파일 액세스 인터페이스를 지원합니다.
비 블로킹, 비 블로킹, 고도로 확장 가능한 네트워크 I/O를 제공합니다.
이 기사는 이러한 기능을 배우고 소개합니다.
4. 버퍼 & 샤넬
채널 및 버퍼는 NIO이며 가장 기본적인 데이터 유형 추상화입니다.
완충기:
연속 메모리 블록입니다.
NIO 데이터를 읽거나 쓰는 대중 교통 장소입니다.
채널:
데이터 소스 또는 데이터 대상
버퍼에 데이터를 제공하거나 버퍼 데이터, 버퍼 객체를 읽는 고유 한 인터페이스.
비동기 I/O 지원
예 1 : CopyFile.java :
패키지 샘플; import java.io.fileInputStream; import java.io.fileoutputStream; import java.nio.bytebuffer; import java.nio.channels.filechannel; public static void main (Strows [] args) 예외 {String Infile = "c : //copy.sql";sql "; "c : //copy.txt"; // 소스 및 대상 파일의 입력 및 출력 스트림을 가져옵니다. fileInputStream FIN = New FileInputStream (infile); fileoutputStream fout = new FileOutputStream (outFile); // 입력 및 출력 channels filechannel fcin = fin.getChannel (); fout. 바이트 버퍼 버퍼 = Bytebuffer.allocate (1024); (true) {// 클리어 메소드는 버퍼를 읽을 수 있도록 버퍼를 재설정하여 데이터 버퍼 (); // 입력 채널에서 버퍼 int r = fcin.read (buffer)로 데이터 읽기 데이터를 읽습니다. 읽기 메소드가 read의 수를 반환합니다. 다른 채널 buffer.flip ()에 데이터를 읽습니다. // 출력 채널에서 버퍼 FCout.write (버퍼)에 데이터를 작성하십시오.}}버퍼의 내부 구조는 다음과 같습니다 (다음 그림은 정보에서 복사됩니다).
그림 2 : 버퍼 내부 구조
버퍼는 주로 세 가지 변수 위치, 한계 및 용량으로 읽기 및 쓰기 프로세스를 제어합니다. 이 세 가지 변수의 의미는 다음 표에 나와 있습니다.
매개 변수 | 쓰기 모드 | 읽기 모드 |
위치 | 현재 작성된 단위 데이터 수. | 현재 단위 데이터 위치를 읽습니다. |
한계 | 최대 데이터의 단위 수를 나타냅니다. | 읽을 수있는 최대 데이터 단위 수를 나타냅니다.이 데이터는 이전에 작성된 단위 데이터의 양과 일치합니다. |
용량 | 버퍼 용량 | 버퍼 용량 |
일반적인 버퍼 방법 :
Flip () : 쓰기 모드를 읽기 모드로 변환합니다
Rewind () : 일반적으로 반복 판독에 사용되는 위치를 0으로 재설정합니다.
CLEAR () : 버퍼를 지우고 다시 작성하도록 준비합니다 (위치는 0이됩니다. 제한은 용량이됩니다).
compact () : 읽지 않은 데이터를 버퍼 헤드에 복사하십시오.
mark (), reset () : Mark는 위치를 표시 할 수 있으며 재설정 이이 위치로 재설정 될 수 있습니다.
일반적인 유형의 버퍼 : 바이트 버퍼, MappedBytebuffer, Charbuffer, Doublebuffer, Floatbuffer, Intbuffer, Longbuffer, Shortbuffer.
공통 채널 : FilEchannel, DataGramChannel (UDP), Socketchannel (TCP), Serversocketchannel (TCP)
이 기계에서 간단한 성능 테스트가 수행되었습니다. 내 노트북은 적당히 수행됩니다. (특정 코드의 첨부 파일을 참조하십시오. nio.sample.filecopy 패키지의 아래 예제 참조) 다음은 참조 데이터입니다.
시나리오 1 : 370m 파일을 복사하십시오
시나리오 2 : 3 개의 스레드 복사는 동시에 복사하고 각 스레드는 370m 파일을 복사합니다.
장면 | FileInputStream+ FileOutputStream | FileInputStream+ BufferedInputStream+ FileOutputStream | 바이트 버퍼+ 필체 채널 | MAPPEDBYTEBUFFER +filechannel |
한 시간 동안 장면 (밀리 초) | 25155 | 17500 | 19000 | 16500 |
장면 2 시간 (밀리 초) | 69000 | 67031 | 74031 | 71016 |
5.nio.charset
문자 인코딩 및 디코딩 : 바이트 코드 자체는 일부 숫자이며 올바른 컨텍스트에서 올바르게 구문 분석됩니다. 바이트 버퍼에 데이터를 저장할 때는 문자 세트의 인코딩 방법을 고려해야합니다. 바이트 버퍼 데이터를 읽고 표시 할 때 문자 세트를 디코딩하는 것이 포함됩니다.
java.nio.charset은 인코딩 및 디코딩을위한 일련의 솔루션을 제공합니다.
가장 일반적인 HTTP 요청을 예로 들어 요청할 때 요청을 올바르게 코딩해야합니다. 응답은 얻을 때 올바르게 디코딩해야합니다.
다음 코드는 Baidu에게 요청을 보내고 디스플레이 결과를 얻습니다. 이 예제는 charset의 사용을 보여줍니다.
예제 2BaidUreader.java
패키지 nio.readpage; import java.nio.bytebuffer; import java.nio.channels.socketchannel; import java.nio.charset.charset; import java.net.inetSocketAddress; import java.io.io.ioexcept; public class baidureader {private charset.forname ( "gbk"); SOODTECHANNE 년 채널; public void reshtmlContent () {try {inetSocketAddress socketAddress = new inetSocketAddress ( "www.baidu.com", 80); // step1 : 연결 채널 열기 = footetchannel.open (socketAddress) (socketAddress) : // 요청을 보내기 "/r/n/r/n")); // step3 : 데이터를 읽으십시오 Bytebuffer 버퍼 = bytebuffer.allocate (1024); // 1024 -byte 버퍼를 만듭니다. system.out.println (charset.decode (buffer)); // charset.decode 메서드를 사용하여 바이트를 string buffer.clear ()로 변환하기 위해} catch (ioexception e) {system.err.println (e.tostring ()); {if (channel! = null) {if (channel.close ()) {if (e.tostring ()); {}}}} public static void main (String [] args) {new BaidUreader (). readhtmlContent ();}}6. 비 블로킹 IO
비 블로킹 IO와 관련하여, 우리는 차단하는 것, 비 블로킹, 비 차단 원리 및 비동기 코어 API의 측면에서 이해할 것입니다.
막힘이란 무엇입니까?
일반적인 네트워크 IO 통신 프로세스는 다음과 같습니다.
이 네트워크 통신 프로세스에서 차단이 무엇인지 이해해 봅시다.
위의 프로세스에 연결이 도착하지 않으면 승인은 블록 블록을 차단하고 여기에서 실행 한 후 프로그램이 중단되어야하며 CPU는 다른 스레드를 실행합니다.
위의 프로세스에서 데이터가 준비되지 않으면 읽기도 차단됩니다.
차단 네트워크 IO의 기능 : 다중 스레딩 다중 연결. 각 스레드에는 자체 스택 공간이 있으며 CPU 시간이 걸립니다. 모든 스레드는 외부 준비가 발생하면 차단됩니다. 차단의 결과는 많은 프로세스 컨텍스트 전환으로 이어질 것입니다. 그리고 대부분의 프로세스 컨텍스트 전환은 의미가 없을 수 있습니다. 예를 들어, 스레드가 포트에 대한 청구를 듣고 하루에 몇 가지 요청 만 있다고 가정하지만 CPU는 스레드에 대한 컨텍스트 전환 시도를 지속적으로 만들어야하며 대부분의 스위칭은 차단으로 끝납니다.
비 차단이란 무엇입니까?
여기에 은유가 있습니다.
A에서 B까지 버스에는 도로에 내릴 수있는 많은 지점이 있습니다. 운전자는 버스에서 어떤 지점이 나올지 모릅니다. 버스에서 내려야하는 사람들을 더 잘 대하는 방법은 무엇입니까?
1. 과정에서 운전자는 정기적으로 각 승객에게 목적지에 도착했는지 여부를 묻습니다. 누군가가 그렇게 말하면 운전자가 멈추고 승객이 내립니다. (차단과 유사)
2. 모든 사람이 티켓 판매자에게 목적지를 말한 다음 잠을 자고 있습니다. 운전자는 티켓 판매자와 만 상호 작용합니다. 그가 특정 지점에 도착하면 티켓 판매자는 승객에게 버스에서 내리도록 통지합니다. (비 블로킹과 유사)
분명히, 목적지에 도달하는 모든 사람은 스레드로 간주 될 수 있으며 운전자는 CPU로 간주 될 수 있습니다. 차단 스타일에서 각 스레드는 대상을 찾는 결과를 달성하기 위해 지속적으로 컨텍스트를 폴링하고 전환해야합니다. 비 블로킹 모드에서는 모든 승객 (스레드)이 자고 있으며 (수면) 실제 외부 환경이 준비 될 때만 깨어납니다. 그러한 모닝은 확실히 차단되지 않을 것입니다.
비 블로킹의 원리
전체 프로세스를 작은 작업으로 전환하고 작업 간의 협업을 통해 완료하십시오.
전용 스레드는 모든 IO 이벤트를 처리하고 배포를 담당합니다.
이벤트 중심 메커니즘 : 이벤트를 동시에 모니터링하지 않고 이벤트가 도착하면 트리거됩니다.
스레드 커뮤니케이션 : 스레드는 대기, 알림 및 기타 수단을 통해 통신합니다. 모든 컨텍스트 스위치가 의미가 있는지 확인하십시오. 불필요한 프로세스 전환을 줄입니다.
다음은 비동기 IO의 구조입니다.
원자로는 티켓 판매자의 은유 적 역할입니다. 각 스레드의 처리 흐름은 아마도 데이터를 읽고, 디코딩하고, 처리를 계산하고, 인코딩하고, 응답을 보내는 것일 수 있습니다.
비동기 IO 코어 API
선택자
하나 이상의 채널에서 이벤트를 감지하고 이벤트를 배포 할 수있는 비동기 IO의 핵심 클래스.
선택 스레드를 사용하여 여러 채널에서 이벤트를 듣고 이벤트 드라이버를 기반으로 해당 응답을 트리거하십시오. 각 채널에 스레드를 할당 할 필요가 없습니다.
선택 키
이벤트의 상태 정보 및 시간에 해당하는 채널의 바인딩이 포함됩니다.
요약
위는 기본 Java 지식 에세이에 대한이 기사의 전체 내용입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!