머리말
이전 기사에서는 추상 디스크 파일의 파일 유형을 소개했습니다. 디스크 파일 또는 디렉토리를 추상적으로 설명하는 데만 사용되지만 파일의 내용에 액세스하고 수정할 수있는 기능은 없습니다.
Java IO 스트림은 파일 내용을 읽고 쓰는 데 사용되는 디자인입니다. 출력 디스크 파일 내용의 데이터 전송을 메모리로 또는 디스크 파일로 출력하여 출력 메모리 데이터를 전송할 수 있습니다.
Java IO 스트림의 디자인은 완벽하지 않습니다. 그것은 많은 클래스를 설계했으며, 이는 IO 스트림에 대한 이해를 높였지만 두 가지 주요 범주 만 있습니다. 하나는 이진 파일의 바이트 스트림이고 다른 하나는 텍스트 파일의 문자 스트림입니다. 이 기사에서는 먼저 관련 바이트 스트림의 원칙과 사용 시나리오를 배웁니다. 주로 관련된 특정 스트림 유형은 다음과 같습니다.
기본 클래스 바이트 스트림 입력/출력
입력 스트림 및 출력 스트림은 각각 바이트 스트림을 읽고 바이트 스트림을 쓰는 기본 클래스입니다. 모든 바이트 관련 스트림은 그 중 하나에서 상속해야합니다. 추상 클래스로서, 그들은 또한 가장 기본적인 읽기 및 쓰기 작업을 정의합니다. 봅시다 :
예를 들어 입력 스트림을 취하십시오.
공개 초록 int read ()는 ioexception을 던졌습니다.
이것은 추상적 인 방법이며, 기본 구현을 제공하지 않으므로 서브 클래스를 구현해야합니다. 이 방법의 목적은 현재 파일의 다음 바이트를 반환하는 것입니다.
물론,이 방법의 반환 값은 정수 유형 "int"를 사용하여 수신되므로 "바이트"를 사용하지 않겠습니까?
우선, 읽기 방법에 의해 반환 된 값은 8 비트 바이너리이어야하며 8 비트 바이너리에 의해 취할 수있는 값 간격은 "0000 0000, 111111111", 즉 범위 [-128, 127]입니다.
읽기 메소드는 또한 파일을 끝까지 읽을 때, 즉 파일에 다음 바이트가 없을 때 값 -1이 반환 될 것을 지정합니다. 따라서 바이트가 리턴 값 유형으로 사용되면 메소드가 -1을 반환 할 때 파일의 데이터 내용인지 스트림 끝인지 확인해야합니까?
int 유형은 4 바이트를 차지하고 높은 비트의 3 바이트는 모두 0입니다. 우리는 가장 낮은 비트 바이트 만 사용합니다. 스트림 플래그의 끝을 만나면 4 바이트로 표시되는 -1 (32 1s)을 반환하며, 이는 데이터를 나타내는 값 -1 (24 0 + 8 1s)과 자연스럽게 다릅니다.
다음은 읽기 메소드이지만 InputStream은 기본 구현을 제공합니다.
public int read (byte b [])는 ioexception {return read (b, 0, b.length);} public int read (byte b [], int off, int len)를 Ioexception {// 길이를 너무 길게 만들지 않기 위해 JDK 소스 코드를 직접 볼 수 있습니다.이 두 가지 방법은 본질적으로 동일합니다. 첫 번째 메소드는 두 번째 방법의 특수 형태로, 바이트 배열을 전달할 수 있으며 배열 길이의 바이트 수를 채우기 위해 배열 인덱스 위치 0에서 시작하는 파일의 바이트를 채우도록 프로그램이 필요합니다.
두 번째 방법은 약간 더 넓으므로 시작 위치와 총 바이트 수를 지정할 수 있습니다.
InputStream에는 기본적으로 구현되지 않은 몇 가지 다른 방법이 있습니다. 간단히 살펴 보겠습니다.
마크 메소드는 현재 스트림 판독 위치에 플래그를 표시하고 재설정 메소드는 플래그에 대한 읽기 포인터를 재설정합니다.
실제로 파일 읽기에 대한 읽기를 다시 재설정하는 것은 불가능하지만 일반적으로 플래그 위치와 재설정 지점 사이의 모든 바이트가 일시적으로 저장됩니다. 재설정 방법이 호출되면 실제로 저장된 임시 바이트 세트에서 반복되는 판독 값이 있으므로 최대 캐시 용량을 제한하는 데 READLIMIT을 사용합니다.
Marksupported 메소드는 현재 스트림 이이 "폴백"읽기 작업을 지원하는지 여부를 결정하는 데 사용됩니다.
OutputStream 및 InputStream은 하나가 쓰여지고 다른 하나는 읽는 것을 제외하고는 유사합니다. 우리는 여기서 그것을 반복하지 않을 것입니다.
파일 바이트 스트림 FileInput/outputStream
우리는 여전히 FileInputStream에 중점을두고 있으며 FileOutputStream은 비슷합니다.
먼저 FileInputStream에는 객체를 인스턴스화하기위한 다음 생성자가 있습니다.
public fileInputStream (문자열 이름)은 filenotFoundException {this (name! = null? 새 파일 (이름) : null);} public fileInputStream (파일)은 filenotFoundException {string name = (file! = null? file.getPath () : null); SecurityManager Security = System.GetSecurityManager (); if (security! = null) {security.checkread (이름); } if (name == null) {throw new nullpointerexception (); } if (file.isinValid ()) {wrach new filenotfoundException ( "유효하지 않은 파일 경로"); } fd = New Filedescriptor (); fd.attach (this); 경로 = 이름; Open (이름);}이 두 생성자는 본질적으로 동일하며 전자는 후자의 특별한 형태입니다. 사실, 후자의 방법을 보지 마십시오. 대부분은 보안 검증을 수행하고 있습니다. 코어는 파일을 열는 데 사용되는 열린 메소드입니다.
주로이 두 생성자, 파일이 존재하지 않거나 파일 경로와 이름이 불법 인 경우 filenotFoundException이 발생합니다.
기본 클래스 입력 스트림에 모든 서브 클래스를 구현 해야하는 추상적 인 메소드가 있으며, FileInputStream은 로컬 메소드를 사용하여 구현된다는 것을 기억하십시오.
public int read ()는 ioexception {return read0 ();} 개인 기본 int read0 ()가 ioexception을 던지 릅니다.당분간 READ0의 특정 구현을 탐색 할 방법은 없지만이 읽기 방법의 기능은 스트림에서 다음 바이트를 반환하고 -1을 반환하는 데 사용된다는 것을 분명히해야합니다. 그것은 파일 끝에 읽히고 읽을 바이트가 없음을 의미합니다.
또한 FileInputStream에는 다른 읽기 관련 방법이 있지만 대부분은 로컬 방법을 사용하여 구현됩니다. 여기를 살펴 보겠습니다.
FileInputStream의 내부 방법은 기본적으로 다음과 같습니다. 당분간 사용할 수없는 고급 및 복잡한 방법이 있습니다. 나중에 배울 것입니다. 파일 읽기의 예를 간단히 살펴 보겠습니다.
public static void main (String [] args)은 ioexception {fileInputStream input = new FileInputStream ( "C : //users//yanga//desktop//test.txt"); 바이트 [] 버퍼 = 새로운 바이트 [1024]; int len = input.read (버퍼); 문자열 str = 새 문자열 (버퍼); System.out.println (str); System.out.println (Len); input.close ();}출력 결과는 매우 간단합니다. 테스트 파일에 내용을 인쇄하고 실제 바이트 수를 읽지 만 신중한 학생들이 알게 될 것입니다. 테스트 파일의 내용이 1024 바이트를 초과하지 않도록하는 방법은 무엇입니까?
파일의 내용을 완전히 읽으려면 하나의 솔루션은 파일의 모든 내용을 가능한 한 많이 저장할만큼 큰 버퍼를 정의하는 것입니다.
이 방법은 파일의 실제 크기를 읽는 것이 불가능하기 때문에 바람직하지 않습니다. 단순히 대형 바이트 배열을 만드는 것은 매우 나쁜 솔루션입니다.
두 번째 방법은 동적 바이트 어레이 스트림을 사용하는 것입니다.이 스트림은 내부 바이트 배열의 크기를 동적으로 조정하여 적절한 용량을 보장 할 수 있으며 나중에 자세히 소개합니다.
FileOutputStream과 관련하여 강조해야 할 것은 하나의 생성자이며 다음과 같은 두 가지 생성자가 있습니다.
public fileoutputStream (문자열 이름, 부울 부록) public fileoutputStream (파일 파일, 부울 부록)
매개 변수 Append는이 스트림의 쓰기 작동이 덮어 쓰거나 첨부되어 있는지, 진정한 수단이 추가되었는지, 허위는 덮어 쓰기를 나타냅니다.
Bytearrayinput/OutputStream
소위 "바이트 어레이 스트림"은 바이트 배열 주위에서 작동하는 스트림입니다. 다른 스트림과 같은 파일에 스트림을 읽고 쓰지 않습니다.
바이트 배열 스트림은 파일 기반 스트림이 아니지만 내부에 캡슐화 된 바이트 배열은 고정되지 않았지만 동적으로 확장 가능하며 종종 특정 시나리오를 기반으로하기 때문에 여전히 매우 중요한 스트림입니다.
BytearRayInputStream은 다음 생성자에 의해 인스턴스화 될 수있는 읽기 바이트 어레이의 스트림입니다.
보호 된 바이트 buf []; 보호 된 int pos; 보호 된 int 수; public bytearrayinputstream (byte buf []) {this.buf = buf; this.pos = 0; this.count = buf.length;} public bytearrayinputstream (byte buf [], int 오프셋, int 길이)BUF는 BytearRayInputStream 내부에 캡슐화 된 바이트 어레이입니다. BytearrayinputStream의 모든 읽기 작업은 그 주위에 회전합니다.
따라서 BytearRayinputStream 객체를 인스턴스화 할 때 적어도 하나의 대상 바이트 배열이 전달됩니다.
POS 속성은 현재 스트림 판독의 위치를 기록하는 데 사용되며 Count는 대상 바이트 배열의 마지막 유효한 바이트 색인의 후자의 위치를 기록합니다.
이것을 이해 한 후에는 다양한 방법을 읽는 것이 어렵지 않습니다.
// 다음 바이트를 읽습니다. 공개 동기화 된 int read () {return (pos <count)? (buf [pos ++] & 0xff) : -1;} // len 바이트를 읽고 바이트 배열 b 공개 동기화 된 int read (byte b [], int off, int len)에 넣습니다.또한 BytearRayinputStream은 "반복 읽기"작업을 매우 간단하게 구현합니다.
public void mark (int readaheadlimit) {mark = pos;} public synchronized void reset () {pos = mark;}BytearrayInputStream은 바이트 어레이를 기반으로하기 때문에 모든 반복 된 읽기 작업은 구현하기 쉽고 인덱스를 기반으로 구현하기에 충분합니다.
BytearRayoutputStream은 작성된 바이트 배열 스트림입니다. 많은 구현에는 여전히 고유 한 특성이 있습니다. 함께 살펴 보겠습니다.
먼저이 두 속성이 필요합니다.
보호 된 바이트 buf []; // 여기에 카운트는 BUF 보호 된 int count의 유효한 바이트 수를 나타냅니다.
건설자:
public bytearrayoutputStream () {this (32);} public bytearrayoutputStream (int size) {if (size <0) {new new INICREALARGUMENTEXCELCE ( "음의 초기 크기 :"+ size); } buf = 새로운 바이트 [size];}생성자의 핵심 작업은 내부 바이트 어레이 BUF를 초기화하여 초기화 된 바이트 배열 크기를 명시 적으로 제한하기 위해 크기를 전달할 수 있도록하는 것입니다. 그렇지 않으면 기본 길이는 32입니다.
외부에서 BytearRayoutputStream에 컨텐츠를 작성하십시오.
public synchronized void write (int b) {ensurecapacity (count + 1); buf [count] = (바이트) b; count + = 1;} public synchronized void Writ } ensurecapacity (count + len); System.ArrayCopy (B, Off, Buf, Count, Len); count += len;}모든 쓰기 작업의 첫 번째 단계는 Ensurecapacity 메소드를 호출하는 것입니다. 목적은 현재 스트림의 바이트 배열 이이 쓰기 작업을 수용 할 수 있도록하는 것입니다.
이 방법은 또한 매우 흥미 롭습니다. 내부 BUF가 계산 후이 쓰기 작업을 지원할 수 없다는 것을 알게되면 성장 방법이 확장을 요구합니다. 용량 확장 원칙은 Arraylist의 원리와 유사하며 원래 용량의 두 배로 확장됩니다.
또한 BytearRayoutputStream에도 WriteTo 메소드가 있습니다.
public synchronized void writeTo (outputStream out) IoException {out.write (buf, 0, count);}내부적으로 캡슐화 된 바이트 배열을 출력 스트림에 쓰십시오.
나머지 방법 중 일부는 또한 매우 일반적으로 사용됩니다.
이 두 개의 스트림을 "스트림"이라고하지만 기본적으로 실제 스트림과 같은 일부 리소스를 할당하지 않으므로 가까운 방법을 호출 할 필요가 없으며이를 호출하는 것은 쓸모가 없습니다 (공무원은 효과가 없습니다).
테스트 케이스는 공개되지 않습니다. 나중에이 기사에 사용 된 모든 코드 케이스를 업로드하겠습니다. 직접 다운로드하도록 선택할 수 있습니다.
길이를 제어하기 위해 나머지 학습은 다음 기사에 배치됩니다.
기사의 모든 코드, 이미지 및 파일은 내 github의 클라우드에 저장됩니다.
(https://github.com/singleyam/overview_java)
로컬로 다운로드하도록 선택할 수도 있습니다.
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.