FileInputStream을 사용하는 것보다 BufferedInputStream을 사용하여 파일을 바이트 단위로 빠르게 읽는 이유는 무엇입니까?
FileInputStream을 사용하여 파일을 배열로 진행하려고했는데 ~ 800KB 파일을 메모리로 읽는 데 약 3 초가 걸렸습니다. 그런 다음 FileInputStream을 BufferedInputStream으로 래핑 한 것을 제외하고 동일한 코드를 시도하고 약 76 밀리 초가 걸렸습니다. BufferedInputStream을 사용하여 파일을 바이트 단위로 읽고 속도가 훨씬 빨라지는 이유는 무엇입니까? 다음은 코드입니다 (나머지 코드는 전혀 관련이 없습니다). 이 "빠른"코드입니다. "느린"코드를 원하면 BufferedInputStream이 제거됩니다.
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
int[] fileArr = new int[(int) file.length()];
for (int i = 0, temp = 0; (temp = is.read()) != -1; i++) {
fileArr[i] = temp;
}
BufferedInputStream은 30 배 이상 빠 사용하지 않습니다. 그 이상입니다. 사용하지 않는 것이 가능하며 외부 라이브러리를 사용하지 않을 수 있습니다.
에서 FileInputStream
, 방법은 read()
단일 바이트를 사용한다. 소스 코드에서 :
/**
* Reads a byte of data from this input stream. This method blocks
* if no input is yet available.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* file is reached.
* @exception IOException if an I/O error occurs.
*/
public native int read() throws IOException;
이 디스크를 사용하여 단일 바이트를 읽는 OS에 대한 기본 호출입니다. 이 무거운 작업입니다.
를 사용 BufferedInputStream
하면 방법는 바이트 양 read()
을 8192
읽을 때 필요한 방법 에 메시지를 전달 합니다. 여전히 단일 바이트 만 반환합니다 (하지만 나머지는 예약 상태로 유지). 이렇게 BufferedInputStream
하면 파일에서 읽기 OS에 대한 기본 호출이 읽기 OS.
예를 들어 파일 32768
길이 는 바이트입니다. 를 사용하여 메모리의 모든 바이트를 가져 오려면 OS에 대한 기본 호출 FileInputStream
이 필요합니다 32768
. 를 사용 하면 수행 할 통화 수에 관계없이 (여전히 ) BufferedInputStream
만 필요합니다 .4
read()
32768
더 빨리 만드는 방법에있는 Java 7의 NIO FileChannel
클래스 를 고려할 수 있습니다.
FileInputStream은 BufferedInputStream은 FileInputStream의 데이터를 큰 덩어리 (기본적으로 512 바이트 정도)로 요청합니다. 따라서 한 번에 하나씩 1000 튼튼하게 읽는 경우 FileInputStream은 디스크로 두 번만 이동하면됩니다. . 이것은 훨씬 빠를 것입니다!
디스크 액세스 비용 때문입니다. 크기가 8kb 인 파일이 가정 해 보겠습니다. BufferedInputStream 없이이 파일을 디스크려면 8 * 1024 회 액세스가 필요합니다.
이 시점에서 BufferedStream은 현장에 가서 FileInputStream과 읽을 파일 사이에서 중개자 역할을합니다.
한 번에 메모리에 8kb의 바이트 청크를 가져오고 FileInputStream 은이 중간 사람으로부터 바이트를 읽습니다. 이렇게하면 작업 시간이 단축됩니다.
private void exercise1WithBufferedStream() {
long start= System.currentTimeMillis();
try (FileInputStream myFile = new FileInputStream("anyFile.txt")) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(myFile);
boolean eof = false;
while (!eof) {
int inByteValue = bufferedInputStream.read();
if (inByteValue == -1) eof = true;
}
} catch (IOException e) {
System.out.println("Could not read the stream...");
e.printStackTrace();
}
System.out.println("time passed with buffered:" + (System.currentTimeMillis()-start));
}
private void exercise1() {
long start= System.currentTimeMillis();
try (FileInputStream myFile = new FileInputStream("anyFile.txt")) {
boolean eof = false;
while (!eof) {
int inByteValue = myFile.read();
if (inByteValue == -1) eof = true;
}
} catch (IOException e) {
System.out.println("Could not read the stream...");
e.printStackTrace();
}
System.out.println("time passed without buffered:" + (System.currentTimeMillis()-start));
}
'ProgramingTip' 카테고리의 다른 글
dis.dis의 출력을 어떻게 이해해야합니까? (0) | 2020.12.04 |
---|---|
지연된 작업 순서를 어떻게 볼 수 있습니까? (0) | 2020.12.04 |
Python에서 고속 푸리에 변환 플로팅 (0) | 2020.12.04 |
Lisp 웹 프레임 워크? (0) | 2020.12.04 |
Lisp는 어떻게 언어 자체를 재정의 할 수 있습니까? (0) | 2020.12.04 |