ProgramingTip

FileInputStream을 사용하는 것보다 BufferedInputStream을 사용하여 파일을 바이트 단위로 빠르게 읽는 이유는 무엇입니까?

bestdevel 2020. 12. 4. 19:51
반응형

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만 필요합니다 .4read()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));
    }

참고 URL : https://stackoverflow.com/questions/18600331/why-is-using-bufferedinputstream-to-read-a-file-byte-by-byte-faster-than-using-f

반응형