1 : 완충 작가
1. 클래스 기능 소개 :
BufferedWriter, 캐시 문자 출력 스트림, 기능은 들어오는 기본 문자 출력 스트림에 대한 캐시 기능을 제공하는 것입니다. 마찬가지로, 기본 문자 출력 스트림을 사용하여 대상에 문자 또는 캐릭터 배열을 작성할 때 대상이 작성 될 때마다 대상에 대한 연결을 열어야합니다. 이러한 빈번한 접근은 지속적으로 효율적이며 저장 매체에 특정 손상을 일으킬 수도 있습니다. 예를 들어, 디스크에 바이트를 지속적으로 작성하면 디스크의 지정된 파일에 g의 매우 큰 단위를 쓰는 것이 과장되며 바이트를 작성하지 않으면이 디스크에 채널을 한 번 열어야합니다. 이 결과는 의심 할 여지없이 끔찍합니다. 그리고 BufferedWriter를 사용하여 FilereAder와 같은 기본 문자 출력 스트림을 래핑 할 때 먼저 프로그램의 파일에 작성하여 버퍼링 라이터의 내장 캐시 공간에 작성된 문자를 작성하고 일정량에 도달하면 FilerEader 스트림에 한 번에 기록됩니다. 현재 FilereAder는 채널을 열고이 데이터 블록을 파일에 쓸 수 있습니다. 하나의 액세스로 모든 데이터를 디스크에 작성하는 효과를 달성하는 것은 불가능하지만 효율성을 크게 향상시키고 디스크 액세스 수를 줄입니다! 이것이 중요성입니다. 특정 작업 원칙은 여기에 간단히 언급되어 있습니다. 여기서는 매우 혼란 스러울 수 있습니다. 소스 코드를 자세히 볼 수 있습니다. 이해하지 못하면 여기를 돌아보십시오. 프로그램에서 캐릭터 또는 캐릭터 배열을 버퍼링 라이터에 작성할 때마다 캐시 된 캐릭터 배열 BUF (BUF의 크기가 기본적이거나 BW를 만들 때 지정된지 여부를 확인합니다. 일반적으로 기본값이 가득 찼습니다). 가득 차 있지 않으면 캐릭터는 Buf로 기록됩니다. 그것이 가득 차 있다면, 기본 작가 (char [] b, int off, int)라고 불립니다. len). 캐릭터 배열이 작성되면 Buf의 모든 캐릭터를 한 번에 쓰기로 작성하면 BUF가 가득 차면 위에 가득 차면 프로세스와 동일합니다. 작성된 캐릭터 배열이 BUF에 저장할 수 있다면, 캐릭터가 저장되고 저술 된 경우, BUF에 저장하십시오. BUF의 모든 문자는 쓰기로 작성한 다음 BUF로 작성할 문자를 저장합니다 (Subscript 0에서 스토리지).
2. BufferedWriter API 소개 :
A : 키워드 개인 작가; 하위 문자 출력 스트림 비공개 CHAR CB []; 버퍼 배열 프라이빗 삽입, Nextchar; NCHARS- NCHARS 크기의 크기, NEXTCHAR- CB Private Static Int DefaultCharbuffersize = 8192의 다음 문자의 서브 스크립트; 기본 CB 크기 개인 문자열 라인 세파 레이터; Newline Method에 사용되는 Newline 캐릭터. 플랫폼마다 값이 다릅니다. B : Construct Method BufferedWriter (Writer Out)는 기본 CB 크기를 사용하여 버퍼링 라이터 BW를 만듭니다. BufferedWriter (Writer Out, Int SZ)는 기본 CB 크기를 사용하여 BufferedWriter BW를 만듭니다. C : 일반 방법 void close ()는이 스트림을 닫고이 스트림과 관련된 리소스를 출시합니다. void FlushBuffer () CB의 캐시 된 문자를 기본 외부로 플러시하고, void flush ()는이 스트림을 새로 고쳐서 기본 스트림 void newline ()을 새로 고칩니다. void write (int c)는 단일 문자를 CB에 씁니다. void write (char cbuf [], int off, int len) 첨자에서 cb void write (string s, int off, int len)로 Len의 문자 길이를 작성하십시오.
3. 소스 코드 분석
package com.chy.io.original.code; import java.io.ioexception; import java.io.printwriter;/*** 문자 출력 스트림에 대한 버퍼링 기능을 제공하고 효율성을 향상시킵니다. 지정된 문자를 사용하여 배열 크기 또는 기본 문자를 버퍼링하여 배열 크기를 버퍼링 할 수 있습니다. */public class bufferedwriter 확장 작가 {// Base Array Private Writer out; // 버퍼 배열 private char cb []; // NCHARS- CB의 총 문자 수, NEXTCHAR- CB Private int Nchars의 다음 문자 첨자, NextChar; // 기본 CB 크기 개인 정적 int DefaultCharbuffersize = 8192; /*** 라인 분리기 문자열. 스트림이 생성 된 순간에 Separator * 속성의 값입니다. * Newline Method에 사용되는 라인 Newline 문자. 플랫폼마다 값이 다릅니다. */ 개인 문자열 라인 세파 레이터; /*** 기본 CB 크기로 BufferedWriter BW를 만듭니다. */ public bufferedwriter (Writer Out) {this (out, defaultcharbuffersize); } / ** * 지정된 CB 크기 * / public bufferedwriter (int sz) {super (out); if (sz <= 0)를 던지는 새로운 불법 불법 행위 ( "버퍼 크기 <= 0")로 Br을 만들고 관련 필드를 초기화합니다. this.out = out; cb = new char [sz]; nchars = sz; nextchar = 0; // 다른 플랫폼에서 Newline 문자 표현을 얻습니다. lineEparator = (string) java.security.accesscontroller.doprivileged (new sun.security.action.getPropertyaction ( "line.separator")); } / ** 기본 문자 출력 스트림이 닫혀 있는지 여부를 감지하십시오* / private void restopen ()는 ioexception {if (out == null) 새로운 ioexception ( "스트림 닫힌"); } /*** CB의 캐시 된 문자를 기본으로 플러시하지만 기본의 문자를 플러시하지는 않습니다. * CLE CB. */ void FlushBuffer ()는 IoException {synchronized (lock) {restopen (); if (nextchar == 0) 반환; out.write (cb, 0, nextchar); NextChar = 0;}} /*** 단일 문자를 CB에 씁니다. */ public void Writ if (nextchar> = nchars) FlushBuffer (); cb [NextChar ++] = (char) c;}} /** * 우리 자신의 작은 최소 방법, java.lang.math를로드하지 않으면 파일 설명자를 실행했는지 * 스택 추적을 인쇄하려고합니다. */ private int min (int a, int b) {if (a <b) 반환 a; return b; } / *** 첨자에서 cb* / public void write (char cbuf [], int off, int len)로 Len의 문자 길이를 쓰십시오. IoException {synchronized (lock) {restopen (); if ((OFF <0) || (OFF> CBUF.length) || (LEN <0) || ((OFF + LEN)> CBUF.LENGTH) || ((OFF + LEN) <0)) {새 IndexOutOfBoundSexception (); } else if (len == 0) {return; } if (len> = nchars) {/* Len이 CB의 길이보다 큰 경우 CB의 기존 문자와 CBUF의 문자는 CB에 글을 쓰지 않고 직접 기록됩니다. */flushbuffer (); out.write (cbuf, off, len); return; } int b = off, t = Off + Len; while (b <t) {int d = min (nchars -nextchar, t -b); system.arraycopy (cbuf, b, cb, nextchar, d); b += d; nextchar += d; if (nextchar> = nchars) flushbuffer (); }}} / *** 문자열의 일부를 cb* / public void write (string s, int off, int len)에 쓰기 IoException {synchronized (lock) {restopen (); int b = off, t = Off + Len; while (b <t) {int d = min (nchars -nextchar, t -b); s.getchars (b, b +d, cb, nextchar); b += d; nextchar += d; if (nextchar> = nchars) flushbuffer (); }}} /*** Newline을 작성하십시오. */ public void newline ()는 ioexception {write (lineseparator); } / ***이 스트림을 새로 고치고 동시에 기본 스트림을 새로 고치십시오* / public void flush ()는 ioexception {synchronized (lock) {flushbuffer (); out.flush ();}} /***이 스트림을 닫고이 스트림과 관련된 리소스를 해제하십시오. */ public void close ()가 IoException {synchronized (lock) {if (out == null) {return; } try {flushbuffer (); } 마침내 {out.close (); out = null; cb = null; }}}}4. 시연 예 : 다음 BufferedReader를 사용하여 문자 유형 파일의 복사를 구현하십시오.
둘 : BufferedReader
1. 클래스 기능 소개 :
버퍼 문자 입력 스트림, 그 기능은 들어오는 기본 문자 입력 스트림에 대한 버퍼링 기능을 제공하는 것입니다. 기본 문자 입력 스트림 (in)의 캐릭터를 자체 버퍼 (내장 캐시 문자 배열)로 읽은 다음 프로그램은 버퍼의 문자를 프로그램에 읽기 위해 버퍼드 리더의 읽기 메소드를 호출합니다. 버퍼의 문자를 읽으면 BufferedReader는 IN 데이터가 읽을 때까지 프로그램을 읽을 수있는 버퍼에서 다음 데이터 블록을 읽습니다. 이를 수행하는 이점은 먼저 읽기 효율을 향상시키고, 둘째, 스토리지 매체를 열기위한 연결 수를 줄입니다. 자세한 이유 때문에 아래에 언급 된 완충 작가. 버퍼의 데이터가 디스크에서 읽는 것보다 10 배 더 빨리 읽을 때마다 데이터를 채우고 버퍼에서 데이터를 채우는 주요 메소드 Fill ()이 있습니다! 이것은 효율성이 매우 끔찍한 개선입니다. 동시에, 우리는 버퍼링 리더의 버퍼 크기를 금지하지 않고 지정할 수 없습니다. 결국, 일회성으로 읽는 데 시간이 오래 걸립니다. 둘째, 메모리 가격은 비교적 비쌉니다. 우리가 할 수있는 것은 합리적인 점을 찾는 것입니다. 일반적으로 BufferedReader를 만들 때 걱정할 필요가없고 버퍼의 기본 크기를 사용할 필요가 없습니다.
2. BufferedReader API 소개 :
A : 구조 메소드 BufferedReader (reader in, int sz)는 지정된 크기 및 기본 문자 입력 스트림에 기초하여 버퍼드 리더를 만듭니다. Br BufferedReader (Reader In) 기본 크기를 사용하여 기본 출력 스트림의 버퍼링 스트림을 사용하여 B : 일반 메소드 void Close ()이 스트림을 닫고이 스트림 void Mark (int readaheadlimit)와 관련된 모든 리소스를 해제합니다. 스트림은 문자를 읽을 수 있습니다 int read ()는 단일 문자를 읽고 정수 형식으로 리턴합니다. IN의 끝이 읽히면 -1을 반환합니다. int read (char [] cbuf, int off, int len) cbuf의 len 문자 읽기 위시 오프에서 시작, 길이 Len String readline () LINE LONG SKIP (long n) CBUF에서 n 문자를 버립니다.
3. 소스 코드 분석
package com.chy.io.original.code; import java.io.ioexception;/*** 기본 문자 입력 스트림에 문자 버퍼링 CB 배열 추가. 효율성 향상 * @version 1.1, 13/11/17 * @authorandychen */public class bufferedReader는 reader {private reader in; 개인 char cb []; 개인 inchchars, Nextchar; 개인 정적 최종 int 무효화 = -2; 비공개 정적 최종 int unmicked = -1; 개인 int markedchar = 표시되지 않은; 개인 int readaheadlimit = 0; /*MarkedChar> 0*// **시에만 유효합니다. 다음 문자가 선 피드 인 경우 건너 뛰십시오*/ private boolean skiplf = false; / ** 마크가 설정되었을 때 skiplf 플래그*/ private boolean markedskiplf = false; Private STATIC INT DEFAULTCHARBUFFERSIZE = 8192; 개인 정적 int defaultexpectedlineLength = 80; /*** 지정된 크기 및 기본 문자 입력 스트림을 기반으로 BufferedReader를 만듭니다. br */ public bufferedReader (reader in, int sz) {super (in); if (sz <= 0) 새로운 불법 불법 행위 렉싱 ( "버퍼 크기 <= 0"); this.in = in; cb = new char [sz]; nextchar = nchars = 0; } / *** 기본 크기를 사용하여 기본 출력 스트림의 버퍼링 스트림을 만듭니다* / public bufferedReader (reader in) {this (in, defaultcharBuffersize); } / ** 기본 문자 입력 스트림이 닫혀 있는지 여부를 감지합니다* / private void restopen ()는 ioexception {if (in == null) 새로운 ioexception ( "스트림 닫힌"); } /*** CB를 채우십시오. */ private void fill ()는 ioexception {int dst; if (markedchar <= unmicked) {/ *no mark */ dst = 0;} else {/ *marked */ int delta = nextchar -markedchar; if (delta> = readaheadlimit) {/ * read-awead 한계를지나 갔다 : 무효화 mark */markedchar = 무효화; readaheadlimit = 0; dst = 0; } else {if (readaheadlimit <= cb.length) { / * 현재 버퍼의 셔플 * / system.arraycopy (cb, markedchar, cb, 0, delta); Markedchar = 0; dst = delta;} else { / * read-ahead 한계를 수용하기 위해 { / * realloce buffer * / char ncb [] = new char [readaheadlimit]; System.ArrayCopy (CB, MarkedChar, NCB, 0, Delta); CB = NCB; Markedchar = 0; dst = delta;} nextchar = nchars = 델타; }} int n; do {n = in.read (cb, dst, cb.length);} while (n == 0); if (n> 0) {nchars = dst + n; NextChar = dst;}} /*** 단일 문자를 읽고 정수로 돌아갑니다. IN의 끝이 읽히면 -1을 반환합니다. */ public int read ()는 ioexception {synchronized (lock) {restopen (); for (;;) {if (nextchar> = nchars) {fill (); if (nextchar> = nchars) return -1;} if (skiplf) {skiplf = false; if (cb [nextchar] == '/n') {NextChar ++; 계속; }} return cb [NextChar ++]; }}} /*** 첨자에서 시작하는 길이 Len에서 in in in in in in in in in in in in in in int read1 (char [] cbuf, int len)에서 시작하는 길이 Len (chbuf, int len)은 ioexception {if (nextChar> = nchars) { /* 요청 된 길이가 버퍼만큼 크지 않다면, 마크 /재판매가 아닌 경우, 그리고 { /*. 로컬 버퍼에 문자. 이런 식으로 버퍼링 된 스트림은 무해하게 캐스케이드됩니다. */ if (len> = cb.length && markedchar <= unmicked &&! skiplf) {return in.read (cbuf, off, len); } fill ();} if (nextchar> = nchars) return -1; if (skiplf) {skiplf = false; if (cb [nextchar] == '/n') {nextchar ++; if (nextchar> = nchars) fill (); if (nextchar> = nchars) return -1; }} int n = math.min (len, nchars -nextchar); System.ArrayCopy (cb, nextchar, cbuf, off, n); nextchar += n; return n; } / *** in in in in to cbuf ~ cbuf ~ index off on in Index off* / public int read (char cbuf [], int off, int len)는 ioexception {synchronized (lock) {restopen (); if ((OFF <0) || (OFF> CBUF.length) || (LEN <0) || ((OFF + LEN)> CBUF.LENGTH) || ((OFF + LEN) <0)) {새 IndexOutOfBoundSexception (); } else if (len == 0) {return 0; } int n = read1 (cbuf, off, len); if (n <= 0) return n; while ((n <len) && in.ready ()) {int n1 = read1 (cbuf, off + n, len -n); if (n1 <= 0) break; n + = n1; } return n;}} / *** 라인을 읽고 줄을 무시하고* / string readline (boolean respline) ioexception {stringbuffer s = null; int startchar; 동기화 (잠금) {restopen (); 부울 omitlf = 무시 || skiplf; bufferLoop : for (;;) {if (nextChar> = nchars) fill (); if (nextChar> = nchars) { / * eof * / if (s! = null && s.length ()> 0) return s.tostring (); Elsereturn Null;} 부울 EOL = False; char c = 0; int i; / * 필요한 경우 남은 '/n'을 건너 뛰십시오 */if (omitlf && (cb [nextChar] == '/n')) nextchar ++; skiplf = false; omitlf = false; Charloop : for (i = nextchar; i <nchars; i ++) {c = cb [i]; if ((C == '/n') || (c == '/r')) {eol = true; break charloop; }} startchar = nextchar; nextchar = i; if (eol) {String str; if (s == null) {str = new String (cb, startchar, i -startchar); } else {s.append (cb, startchar, i -startchar); str = s.tostring (); } nextchar ++; if (c == '/r') {skiplf = true; } return str;} if (s == null) s = new StringBuffer (defaultexpectedlinElength); s.append (cb, startChar, i -startChar); }}} / ** * in, * / public string readline ()가 IoException {return readline (false); } / **** / public long skip (long n)에 n 문자를 버립니다. ioexception {if (n <0l) {throw new new OregalArgumentException ( "스킵 값은 음수"); 긴 r = n; while (r> 0) {if (nextchar> = nchars) fill (); if (nextchar> = nchars)/ * eof */ break; if (skiplf) {skiplf = false; if (cb [nextchar] == '/n') {NextChar ++; }} long d = nchars -nextchar; if (r <= d) {nextchar += r; r = 0; break;} else {r- = d; nextchar = nchars;}} return n -r;}} / ** * CB가 비어 있는지 또는 기본에 읽을 수있는 문자가 있는지 결정합니다. * / public boolean ready ()는 ioexception {synchronized (lock) {restopen (); / * * Newline을 건너 뛰고 다음 숯을 읽을 필요가있는 경우 *가 Newline 캐릭터 인 경우 즉시 건너 뛰십시오. */ if (skiplf) {/ * in.ready ()가 스트림의 다음 읽기가 차단되지 않는 경우에만 true를 반환합니다. */if (nextChar> = nchars && in.ready ()) {fill ();} if (nextChar <nchars) {if (cb [nextChar] == '/n') nextchar ++; skiplf = false;}} return (nextchar <nchars) || in.ready ();}} / ***이 스트림이 마크를 지원하는지 여부를 결정하십시오* / public boolean marksupported () {return true; } /*** 현재이 스트림의 위치를 표시하고 재설정 메소드를 호출하기 전에 ReadaheadLimit 문자로 읽을 수 있습니다. */ public void mark (int readaheadlimit)는 ioexception {if (readaheadlimit <0) {throw new new eblegalArgumentException ( "read-ahead limit <0");} synchronized (lock) {restopen (); this.readaheadlimit = readaheadlimit; Markedchar = Nextchar; markedskiplf = skiplf;}} /*** IN이 마지막으로 표시된 위치를 재설정합니다. 즉, 다음 캐릭터는 마지막으로 표시된 위치에서 읽습니다. */ public void reset ()는 ioexception {synchronized (lock) {restopen (); if (markedchar <0) 새로운 ioexception을 던지십시오 ((markedchar == invalidated)? "mark invalid": "stream not marked"); nextchar = markedchar; skiplf = markedskiplf;}} //이 스트림을 닫고이 스트림과 관련된 모든 리소스를 해제합니다. public void close ()는 ioexception {synchronized (lock) {if (in == null) return; 넣다(); in = null; cb = null;}}}4. 시연 예 :
package com.chy.io.original.test; import java.io.bufferedReader; import java.io.bufferedWriter; import java.io.file; import java.io.filereader; import java.io.filewriter; import java.io.filewereTern java.io.ioexmence; import java.io.filewerectorn; {/*** 여기서이 두 클래스의 테스트는 비교적 간단합니다. 파일 문자 스트림을 래핑하고 파일 복사를 구현하는 것입니다.* 관심이 있으시면 효율성을 테스트하고 게으르며*/public static void main (String [] args)을 IoException = 새 파일 ( "d : //test.txt"); 파일 ( "e : //copyoftest.txt"); bufferedReader br = new bufferedReader (new filereader (resouceFile)); bufferedWriter bw = new bufferedWriter (new filewriter (targetfile)); char [] cbuf = new char [1024]; int n = 0; (n = br.read (cbuf))! -1) {bw.write (cbuf, 0, n);} // 흐름을 새로 고치고 닫는 것을 잊지 마십시오. 그렇지 않으면 한편으로는 시간이 제 시간에 해제되지 않으며 다른 한편으로는 br.close (); bw.close ();}}가 데이터 손실을 일으킬 수 있습니다.요약 :
BufferedReader 및 BufferedWriter의 경우, 본질은 기본 문자 입력 및 출력 스트림에 버퍼링 기능을 추가하고 먼저 한 번에 읽기 그룹 형태로 기본 스트림의 데이터를 읽거나 쓰는 다음 버퍼에서 작동하는 것입니다. 이것은 효율성뿐만 아니라 자원을 절약합니다. 마지막으로, 프로그램에서 효율성 이유로,이 두 클래스는 하천을 잡고 직접 업로드하는 대신 저수준 스트림에 사용하여 실현 될 수 있다고 생각해야합니다.