> 类库下载 > java类库 > Java 파일 I/O의 세 가지 방법

Java 파일 I/O의 세 가지 방법

高洛峰
풀어 주다: 2016-10-12 17:53:31
원래의
1954명이 탐색했습니다.

이전에 인터뷰에서 Java로 파일읽기와 출력을 작성하는 방법에 대한 질문을 두 번 받았습니다. 당시에는 대략적인 아이디어만 기억하고 명확하게 설명할 수 없었습니다. 오늘은 이 부분을 특별히 요약해서 작성하고 싶었습니다. 아래로 내려가서 모두와 공유하세요.

우선, 일반적으로 사용되는 세 가지 파일 읽기 및 출력 스트림이 있습니다: FileInputStream/FileOutputStream, FileReader/FileWriter 및 RandomAccessFile. 참고할 수 있는 몇 가지 간단한 예는 다음과 같습니다.

기본:

1.

FileRead fr = new FileReader(filename);  
String s;  
while( (s=fr.readLine())!=null){  
...  
}  
fr.close();  
//FileWriter同理,输出时可用write()函数  
//Java I/O中所有的Reader、Writer都是面向字符流的输出输出
로그인 후 복사

2.

FileInputStream fi =new FileInputStream(filename);  
int in;  
while( (in=fi.read())!=-1){  
...  
}  
fi.close();  
//FileOutputStream同理  
//Java I/O中所有的Reader、Writer都是面向字节流的输出输出
로그인 후 복사

3.

RandomAccessFile ra =new RandomAccessFile(filename,"rw");//后面的参数指定的是  
打开文件流的方式,“rw”是指读写,“r”是只读,Java不提供只写  
ra.seek(number);//将文件指针移动到number处,这里文件指针可以理解为文件开始读的位置  
ra.skipByte(number);//跳过number个字节  
ra.read();  
ra.close();  
//RandomAccessFile既可以读也可以写,而且可以利用seek()函数指定位置
로그인 후 복사

다음은 Baidu Encyclopedia의 일부 소개입니다.

RandomAccessFile은 InputStream 및 OutputStream 범주에 속하지 않습니다. 실제로 DataInput 및 DataOutput 인터페이스(DataInputStream 및 DataOutputStream도 이 두 인터페이스를 구현함)를 구현하는 것 외에는 이 두 클래스와 아무런 관련이 없으며, InputStream 및 OutputStream이 준비한 함수도 사용하지 않습니다. 완전히 독립적인 클래스이며 모든 메서드(대부분 자체에 속함)가 처음부터 작성됩니다. 이는 RandomAccessFile이 파일 내에서 앞뒤로 이동할 수 있기 때문에 해당 동작이 다른 I/O 클래스와 근본적으로 다르기 때문일 수 있습니다. 전체적으로 Object를 직접 상속하는 독립 클래스입니다.

고급 기사:

nio에서 Java는 I/O 스트림을 다시 구현하고 속도를 향상시키는 몇 가지 새로운 방법을 도입합니다. 채널과 메모리 매핑 파일을 주로 소개합니다

1. 채널:

채널과 버퍼는 쌍을 이루는 개념입니다. Thinking in Java의 예는 특히 이해하기 쉽습니다. 읽기 파일은 탄광으로 간주되며 데이터는 우리가 원하는 석탄입니다. 수로는 석탄을 운반하는 컨베이어 벨트와 같습니다. 컨베이어 벨트에서 직접 석탄을 꺼낼 수 있는 방법이 없기 때문에 트럭을 이용해 석탄을 꺼내는 역할을 주로 담당합니다. 채널의 데이터를 우리가 작성한 프로그램에 전달합니다. 채널과 상호 작용할 수 있는 유일한 버퍼는 ByteBuffer입니다. 채널이 지원하는 스트림을 파싱하는 방식이 바이트 스트림임을 알 수 있다. 그래서 FileInputStream/FileOutputStream, RandomAccessFile

을 사용합니다. 예:

a.

FileChannel fc =new FileOutputStream(filename).getChannel();  
fc.write(ByteBuffer.wrap("something test".getBytes() ));//这里使用ByteBuffer比较简单,其实ByteBuffer可以利用个put()函数写入byte数组  
fc.close();
로그인 후 복사

b.

fc= new FileOutputStream(filename).getChannel();  
ByteBuffer buff = ByteBuffer.allocate(size);//没错,ByteBuffer是不提供显示构造函数的,想要新建一个对象必须利用allocate()函数来分配空间。  
fc.read(buff);  
fc.close();
로그인 후 복사

왜 그렇게 생각하시나요? ? I/O에 채널을 사용하는 경우 가장 중요한 점은 성능입니다. 채널과 버퍼를 사용하면 프로그램이 특정 양의 문자를 읽고 쓸 수 있지만, Reader/Writer는 1바이트만 읽고 쓸 수 있습니다. 시간/문자. 프로그램이 I/O를 수행할 때 이 부분(시스템 호출 호출)을 해결하려면 운영체제에 넘겨주어야 합니다. 운영체제에 넘겨주는 횟수를 줄이면 I/O에 소요되는 시간을 효과적으로 줄일 수 있습니다. O

2. 메모리 매핑 파일:

메모리 매핑 파일의 주요 의미는 실제로 파일이 메모리에 저장되고 매우 큰 배열로 액세스된다는 것을 가정하므로 매우 효율적입니다. 왜 더 좋은가? Java Virtual Machine과 운영체제부터 시작한다. (사실 잘 이해가 안 된다. 방금 명확하게 설명하는 글을 읽었다. 링크는 http://www.360doc.com/이다. 내용 ...) 이 글에서는 주로 Java I/O의 원리와 메모리 매핑 파일의 원리를 소개합니다. 요약하자면, Java I/O의 주요 구현 방법은 확실히 시스템 호출을 사용하는 것이며, 시스템 호출은 먼저 사용하려는 파일을 하드 디스크에서 커널의 I/O 버퍼로 전송합니다. , Java 프로그램을 가져옵니다. 파일에 더 많은 내용을 복사하려는 경우(더 많은 내용을 복사하는 것은 더 나은 효율성을 얻을 수 있는 프로그램의 지역성 원칙 때문입니다) 커널의 I/O 버퍼에서 Java로 가져옵니다. 프로세스 자신의 개인 메모리 공간. 메모리 매핑 파일은 2개의 복사본을 사용하는 방식을 버리고 Java 프로세스의 가상 공간과 파일 객체 사이에 직접 매핑을 형성하며, 전용 메모리 공간에서 원하는 내용을 찾을 수 없을 경우 페이지 폴트 예외가 발생한다. 이 문제를 해결하기 위해 호출이 사용됩니다(실제로 I/O 시스템 호출에도 페이지 오류 예외 처리가 포함됩니다). 장점은 커널 I/O 버퍼에서 프로세스 전용으로의 오버헤드를 줄이는 것입니다. 주소.

예:

FileChannel fc = new RandomAccessFile(filename,"rw").getChannel();  
MappedByteBuffer mb = fc.map(FileChannel.MapMode.READ_WRITE,start,length);  
mb.put((byte)'x');  
mb.get();  
fc.close();
로그인 후 복사

이 글을 쓰다가 갑자기 "공이지"에서 "회향"을 쓰는 4가지 방법이 생각났습니다. 이제 Java에서 파일을 여는 방법은 최소한 5가지가 있습니다. , 각 종에는 고유한 장단점이 있습니다. 이제부터는 가운을 입고 다른 사람에게 자바로 파일을 읽고 쓰는 5가지 방법을 아느냐고 물어봐도 됩니다

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿