머리말
이전 기사에서는 Java 파일 바이트 스트리밍 프레임 워크에 관련 내용을 소개했으며 기사는 파일 문자 스트리밍의 관련 내용에 중점을 둘 것입니다.
우선, 바이트 스트림 처리 파일은 바이트를 기반으로하는 반면, 문자 스트림 처리 파일은 문자를 기본 단위로 기반으로합니다.
그러나 실제로 문자 스트림 작동의 본질은 "바이트 스트림 작동" + "인코딩"의 두 프로세스의 캡슐화입니다. 그렇게 생각하세요? 문자를 파일에 작성하든 문자를 바이너리로 인코딩 한 다음 기본 단위로 바이트로 파일에 작성하거나 메모리에 문자를 읽은 다음 기본 장치로 바이트로 읽은 다음 문자로 트랜스 코드해야합니다.
이를 이해하는 것이 중요하며, 이는 캐릭터 스트림에 대한 전반적인 이해를 결정할 것입니다. 관련 API의 디자인을 함께 살펴 보겠습니다.
기본 클래스 리더/작가
캐릭터 스트림 기본 클래스를 공식적으로 배우기 전에 캐릭터가 Java에서 어떻게 표현되는지 알아야합니다.
우선, Java에서 인코딩하는 기본 문자는 UTF-8이며 UTF-8 인코딩 된 문자는 1 ~ 4 바이트를 사용하여 저장되며보다 일반적으로 사용되는 문자는 더 적은 바이트가 사용됩니다.
숯 유형은 2 바이트 크기로 정의됩니다. 즉, 일반적인 캐릭터의 경우 숯은 문자를 저장할 수 있지만 일부 보완적인 문자 세트의 경우 두 숯이 종종 문자를 나타내는 데 사용됩니다.
독자는 캐릭터 스트림을 읽기위한 기본 클래스이며 가장 기본적인 캐릭터 읽기 작업을 제공합니다. 함께 살펴 보겠습니다.
먼저 생성자를 살펴 보겠습니다.
Protected Object Lock; Protected Reader () {this.lock = this;} Protected Reader (Object Lock) {if (lock == null) {throw new nullpointerexception (); } this.lock = lock;}리더는 추상 클래스이므로 이러한 생성자는 서브 클래스로 호출되고 잠금 잠금 객체를 초기화하는 데 사용되며 나중에 자세히 설명 할 것입니다.
public int read ()는 ioexception {char cb [] = new char [1]; if (read (cb, 0, 1) == -1) return -1; else return cb [0];} public int read (char cbuf [])는 ioexception {return read (cbuf, 0, cbuf.length);} 추상 public int read (char cbuf [], int off, int len)기본 캐릭터 읽기 작업이 모두 여기에 있습니다. 첫 번째 방법은 캐릭터를 읽는 데 사용됩니다. 파일의 끝까지 읽은 경우 -1을 반환합니다. int도 반환 값 유형과 마찬가지로 수신됩니다. char를 사용하지 않는 이유는 무엇입니까? 그 이유는 값 -1의 해석의 불확실성으로 인해 동일합니다.
두 번째 방법은 세 번째 방법과 유사하며 파일에서 지정된 길이의 문자를 읽고 대상 배열에 배치합니다. 세 번째 방법은 초록 방법으로 서브 클래스로 구현해야하며 두 번째 방법은이를 기반으로합니다.
유사한 다른 방법이 있습니다.
이러한 방법은 실제로 잘 알려져 있으며 일반적으로 입력 스트림과 유사하며 핵심 구현이 없습니다. 나는 여기서 세부 사항으로 들어 가지 않을 것입니다. 당신은 그 안에 무엇이 있는지 알 수 있습니다.
Writer는 서면 캐릭터 스트림으로, 하나 이상의 문자를 파일에 작성하는 데 사용됩니다. 물론, 특정 쓰기 방법은 여전히 추상적 인 방법이며 서브 클래스에 의해 구현되어야하므로 여기에서 반복하지 않을 것입니다.
어댑터 InpustStramReader/outputStreamwriter
어댑터 캐릭터 스트림은 캐릭터 스트림 시스템의 매우 중요한 멤버 인 기본 클래스 리더 또는 작가의 상속을받습니다. 주요 기능은 바이트 스트림을 문자 스트림으로 변환하는 것입니다. 먼저 읽기 어댑터를 예로 들어 봅시다.
우선, 핵심 구성원 :
개인 최종 스트림 디코더 SD;
StreamDecoder는 바이트의 다양한 작업을 해당 문자 작업으로 변환하는 데 사용되는 디코더입니다. 우리는 후속 소개에서 지속적으로 언급 할 것이며, 여기에서 균일하게 설명하지 않을 것입니다.
그런 다음 생성자가 있습니다.
public inputStreamReader (inputStream in) {super (in); try {sd = streamdecoder.forinputStreamReader (in, this, (string) null); } catch (UnsupportedEncodingException e) {새로운 오류 (E); }} public inputStreamReader (inputStream in, String charSetName)는 unsupportedEncodingException {super (in); if (charsetname == null) 새 nullpointerexception ( "charsetname"); sd = streamdecoder.forinputStreamReader (in, this, charsetname);}이 두 생성자의 목적은이 디코더를 초기화하는 것입니다. inputStreamReader에 대한 메소드는 호출되지만 매개 변수는 다릅니다. 이 방법의 구현을 살펴 보겠습니다.
이것은 전형적인 정적 공장 패턴입니다. 바이트 스트림 인스턴스와 어댑터 인스턴스를 각각 나타내는 세 가지 매개 변수 인 VAR0 및 VAR1에 대해 할 말이 없습니다.
매개 변수 var2는 실제로 문자 인코딩 이름을 나타냅니다. NULL 인 경우 시스템 기본 문자 인코딩이 사용됩니다 : UTF-8.
마지막으로 디코더 인스턴스를 얻을 수 있습니다.
다음에 도입 된 거의 모든 방법은이 디코더에 의존하여 구현됩니다.
public string getencoding () {return sd.getencoding ();} public int read ()는 ioexception {return sd.read ();} public int read (char cbuf [], int offset, int length) {return sd.read (cbuf, 오프셋, 길이);} public void () {sd.close ();디코더에서 관련 방법의 구현 코드는 여전히 비교적 복잡합니다. 우리는 여기서 심층적 인 연구를 수행하지는 않지만 일반적인 구현 아이디어는 "바이트 스트림 읽기 + 디코딩"의 과정입니다.
물론, 캐릭터 인코딩을 위해 outputStreamwriter에 Streamencoder 인스턴스가 반대 방향이 있어야합니다.
이 외에도, 나머지 작업은 문자 배열을 통해 파일에 기록되거나 문자열을 통해 파일에 작성하거나 int의 16 비트를 통해 파일에 기록됩니다.
파일 문자 스트림 Filereader/Writer
파일의 문자 스트림은 매우 간단하다고 말할 수 있습니다. 생성자를 제외한 다른 방법은 없으며 전적으로 파일 바이트 스트림에 따라 다릅니다.
Filereader를 예로 들어 봅시다.
Filereader는 InputStreamReader에서 상속하고 다음과 같은 세 가지 생성자 만 가지고 있습니다. public filereader (String Filename)는 filenotfoundException {super (filenOnputStream (filename));} public fileReader (파일 파일) throws filenotfoundException {Super PleputStream (filer putstream (file));} fileInputStream (fd));}이론적으로, 모든 문자 스트림은 어댑터를 기반으로해야합니다. 글을 쓰든 읽든 읽거나 읽든 바이트로 변환을 제공하기 때문에 분리 할 수 없기 때문입니다.
우리의 Filereader는 자체 방법을 확장하지 않습니다. 부모 클래스 inputStreamReader에서 사전 구축 된 문자 작업 방법으로는 충분합니다. 그는 해당 바이트 스트림 인스턴스 만 전달하면됩니다.
Filewriter에게도 마찬가지입니다. 여기서는 자세히 설명하지 않습니다.
문자 배열 스트림 charArrayReader/Writer
캐릭터 배열 및 바이트 어레이 스트림은 파일 크기가 불확실하고 많은 양의 컨텐츠를 읽어야하는 상황을 해결하기 위해 비슷합니다.
내부적으로 동적 확장 메커니즘을 제공하기 때문에 대상 파일을 수용 할뿐만 아니라 너무 많은 메모리를 할당하고 많은 메모리 공간을 낭비하지 않도록 배열 크기를 제어 할 수 있습니다.
charArrayReader를 예로 들어 보겠습니다
보호 된 char buf []; public charArrayReader (char buf []) {this.buf = buf; this.pos = 0; this.count = buf.length;} public charArrayReader (char buf [], int 오프셋, int 길이) {// ..}생성자의 핵심 작업은 문자 배열을 내부 BUF 속성으로 초기화하는 것입니다. 문자 배열 스트림 인스턴스의 모든 후속 읽기 작업은 BUF 문자 배열을 기반으로합니다.
Chararrayreader와 Chararraywriter의 다른 방법과 관련하여, 나는 여기에서 그것들을 반복하지 않을 것입니다. 이들은 기본적으로 이전 기사의 바이트 배열 스트림과 유사합니다.
또한 StringReader와 StringWriter도 관련이 있습니다. 실제로, 그것은 본질적으로 문자 배열 스트림과 동일합니다. 결국, 문자열의 본질은 숯 배열입니다.
BufferedReader/Writer
마찬가지로, BufferedReader/Writer는 버퍼 스트림이며, 버퍼링 기능을 제공하는 데 사용되는 데코레이터 스트림이기도합니다. 일반적으로 바이트 버퍼 스트림과 유사하게 여기에 간단히 소개하겠습니다.
개인 독자; 개인 char cb []; private static int defaultcharbuffersize = 8192; public bufferedReader (reader in, int sz) {..} public bufferedReader (reader in) {this (in, defaultcharBuffersize);}CB는 파일 스트림에서 읽는 문자를 캐시하는 문자 배열입니다. 생성자 에서이 배열의 길이를 초기화 할 수 있습니다. 그렇지 않으면 기본값 8192가 사용됩니다.
public int read ()는 ioexception {..} public int read (char cbuf [], int off, int len) {...}읽기와 관련하여, 그것은 멤버 속성의 읽기 메소드에 의존한다.
따라서 거의 모든 문자 스트림은 바이트 스트림 인스턴스와 분리 될 수 없습니다.
BufferedWriter에 대해 여기서 반복하지 않을 것입니다. 하나는 읽고 있고 다른 하나는 글을 쓰고 있으며 내부 문자 배열을 중심으로 진행된다는 것을 제외하고는 기본적으로 비슷합니다.
표준 인쇄 스트림
인쇄물 스트림에는 두 가지 주요 유형의 인쇄물이 있습니다. 전자는 바이트 스트림이고 후자는 캐릭터 스트림입니다.
이 두 스트림은 해당 범주의 스트림을 통합하는 것으로 간주됩니다. 풍부한 내부 캡슐화 방법이 있지만 구현도 약간 복잡합니다. 먼저 PrintStream 바이트 스트림을 살펴 보겠습니다.
몇 가지 주요 생성자가 있습니다.
분명히, 간단한 생성자는 복잡한 생성자에 의존 할 것이며, 이는 이미 JDK 디자인을위한 "오래된 루틴"으로 간주됩니다. 다른 바이트 스트림과 구별되는 것은 PrintStream이 캐시를 자동으로 새로 고치는 지 여부를 지정하는 플래그 자동 플러시를 제공한다는 것입니다.
다음은 PrintStream의 작문 방법입니다.
또한 PrintStream은 많은 인쇄 방법을 캡슐화하고 다음과 같은 파일에 다양한 유형의 컨텐츠를 씁니다.
물론 이러한 방법은 실제로 숫자 바이너리를 파일에 쓰는 것이 아니라 해당 문자열을 파일에 작성합니다.
인쇄 (123);
최종 파일은 123에 해당하는 바이너리어가 아니라 인쇄 스트림 인 String 123만이됩니다.
PrintStream에서 사용하는 버퍼링 된 문자 스트림은 모든 인쇄 작업을 구현합니다. 자동 새로 고침이 지정되면 Newline 기호 "/n"을 만나면 버퍼가 자동으로 새로 고침됩니다.
따라서 PrintStream은 바이트 스트림 및 문자 스트림에 모든 출력 방법을 통합하며, 여기서 쓰기 방법은 바이트 스트림 작업에 사용되며 인쇄 방법은 문자 스트림 작업에 사용되며 명확해야합니다.
Printwriter의 경우 캐릭터와 완전히 작동하는 전체 캐릭터 스트림입니다. 쓰기 방법이든 인쇄 방법이든, 문자 스트림 작동입니다.
요약하면, 우리는 Java에서 바이트 스트림과 문자 스트림 작업을 설명하는 3 개의 기사를 보냈습니다. 바이트 스트리밍은 바이트를 기반으로 디스크와 메모리 사이의 데이터 전송을 완료합니다. 가장 일반적인 것은 파일 문자 스트림이며 구현은 모두 로컬 방법입니다. 기본 바이트 전송 기능을 통해 버퍼링을 통해 효율성을 향상시킬 수도 있습니다.
문자 스트림의 가장 기본적인 구현은 InputStreamReader 및 OutputStreamWriter입니다. 이론적으로는 이미 기본 문자 스트림 작업을 완료 할 수 있지만 가장 기본적인 작업으로 제한됩니다. 인스턴스를 구성하는 데 필요한 것은 "바이트 스트림 인스턴스" + "인코딩 형식"입니다.
따라서 문자 스트림과 바이트 스트림 사이의 관계는 위의 방정식과 같습니다. 디스크 파일에 문자를 작성하는 데 필요한 단계는 지정된 인코딩 형식으로 문자를 인코딩 한 다음 바이트 스트림을 사용하여 인코딩 된 문자 바이너리를 파일에 씁니다. 읽기 작업이 반대입니다.
기사의 모든 코드, 이미지 및 파일은 내 github의 클라우드에 저장됩니다.
(https://github.com/singleyam/overview_java)
로컬로 다운로드하도록 선택할 수도 있습니다.
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.