Рубрики
Без рубрики

Как прочитать файл в Java – FileInputStream

В Java мы используем FileInputStream для чтения байтов из файла, такого как файл изображения или двоичный файл.

В Java мы используем FileInputStream для чтения байтов из файла, такого как файл изображения или двоичный файл.

Темы

  1. Поток ввода файла – Чтение файла
  2. Поток ввода файла – Оставшиеся байты
  3. Поток ввода файлов – Более высокая производительность
  4. Поток ввода файла против потока ввода буфера
  5. InputStreamReader – Преобразование потока ввода файла в средство чтения
  6. FileInputStream – Чтение файла в Юникоде

Примечание Однако во всех приведенных ниже примерах используется FileInputStream чтобы прочитать байты из текстового файла и распечатать их. Текстовый файл позволяет читателям правильно “видеть” вывод. Как правило, мы используем Считыватель для чтения символов из текстового файла.

1. Входной поток файла – Прочитать файл

В этом примере используется FileInputStream для чтения байтов из файла и распечатки содержимого. fis.read() считывает байт за раз, и он вернет -1 если он достиг конца файла.

package com.mkyong.io.api.inputstream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamExample1 {

    public static void main(String[] args) {
        readFile("c:\\test\\file.txt");
    }

    private static void readFile(String fileName) {

        try (FileInputStream fis = new FileInputStream(new File(fileName))) {
            int content;
            // reads a byte at a time, if it reached end of the file, returns -1
            while ((content = fis.read()) != -1) {
                System.out.println((char)content);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

2. Входной поток файла – Оставшиеся байты

Мы можем использовать fis.available() для проверки оставшихся байтов, которые можно прочитать. Например:

Ниже приведен текстовый файл, содержащий 10 байт.

mkyong.com
package com.mkyong.io.api.inputstream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamExample2 {

    public static void main(String[] args) {
        readFile("c:\\test\\file.txt");
    }

    private static void readFile(String fileName) {

        try (FileInputStream fis = new FileInputStream(new File(fileName))) {

            // remaining bytes that can be read
            System.out.println("Remaining bytes that can be read : " + fis.available());

            int content;
            // reads a byte at a time, if end of the file, returns -1
            while ((content = fis.read()) != -1) {
                System.out.println((char) content);

                System.out.println("Remaining bytes that can be read : " + fis.available());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Выход

Remaining bytes that can be read : 10
m
Remaining bytes that can be read : 9
k
Remaining bytes that can be read : 8
y
Remaining bytes that can be read : 7
o
Remaining bytes that can be read : 6
n
Remaining bytes that can be read : 5
g
Remaining bytes that can be read : 4
.
Remaining bytes that can be read : 3
c
Remaining bytes that can be read : 2
o
Remaining bytes that can be read : 1
m
Remaining bytes that can be read : 0

Для файла, содержащего файл размером 10 байт, first.read() будет выполняться десять раз и каждый раз считывать байт. (Видите здесь проблему?)

3. Поток ввода файлов – Более высокая производительность

3.1 Просмотрите исходный код FileInputStream#read() , каждый read() вызовет собственный метод для чтения байта с диска.

package java.io;

public class FileInputStream extends InputStream {

    /**
     * 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 -1 if the end of the
     *             file is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public int read() throws IOException {
        return read0();
    }

    private native int read0() throws IOException;

    //...
}

3.2 Мы можем использовать чтение(байт b[]) для чтения предопределенных байтов в массив байтов; это значительно увеличит производительность чтения.

package com.mkyong.io.api.inputstream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FileInputStreamExample3 {

    public static void main(String[] args) {
        readFileBetterPerformance("c:\\test\\file.txt");
    }

    private static void readFileBetterPerformance(String fileName) {

        try (FileInputStream fis = new FileInputStream(new File(fileName))) {

            // remaining bytes that can be read
            System.out.println("Remaining bytes that can be read : " + fis.available());

            // 8k a time
            byte[] bytes = new byte[8192];

            // reads 8192 bytes at a time, if end of the file, returns -1
            while (fis.read(bytes) != -1) {

                // convert bytes to string for demo
                System.out.println(new String(bytes, StandardCharsets.UTF_8));

                System.out.println("Remaining bytes that can be read : " + fis.available());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Приведенный выше пример будет гласить 8192 байт за раз, а для файла, содержащего 10 байт, он считывается только один раз.

Remaining bytes that can be read : 10
mkyong.com
Remaining bytes that can be read : 0

Примечание Например, если файл, содержащий 81920 байт (80 кб), значение по умолчанию .read потребует 81920 собственных вызовов для чтения всех байтов из файла; В то время как fis.read(байт) (для размера 8192) нам нужно всего 10 собственных вызовов. Разница огромна.

4. Поток ввода файла против потока ввода буфера

Поток FileInputStream считывает байт за раз, и каждый read() будет собственным считыванием с диска. Для чтения большого файла это замедлится.

Буферизованный входной поток считывает 8192 байт (по умолчанию) за раз и буферизует их до тех пор, пока они не понадобятся; BufferedInputStream#read() по-прежнему возвращает по одному байту за раз, но остальные оставшиеся байты находятся в буфере и зарезервированы для следующего чтения. Концепция аналогична описанной выше Концепция аналогична описанной выше

Обычная практика использует BufferedInputStream для обертывания FileInputStream для обеспечения буферного кэша для повышения производительности чтения.

package com.mkyong.io.api.inputstream;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamExample4 {

    public static void main(String[] args) {
        readFileBetterPerformance2("c:\\test\\file.txt");
    }

    private static void readFileBetterPerformance2(String fileName) {

        try (BufferedInputStream bis =
                     new BufferedInputStream(
                             new FileInputStream(new File(fileName)))) {

            // remaining bytes that can be read
            System.out.println("Remaining bytes that can be read : " + bis.available());

            int content;
            // reads 8192 bytes at a time and buffers them until they are needed,
            // if end of the file, returns -1
            while ((content = bis.read()) != -1) {

                // convert bytes to string for demo
                System.out.println((char) content);

                System.out.println("Remaining bytes that can be read : " + bis.available());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Выход

Remaining bytes that can be read : 10
m
Remaining bytes that can be read : 9
k
Remaining bytes that can be read : 8
y
Remaining bytes that can be read : 7
o
Remaining bytes that can be read : 6
n
Remaining bytes that can be read : 5
g
Remaining bytes that can be read : 4
.
Remaining bytes that can be read : 3
c
Remaining bytes that can be read : 2
o
Remaining bytes that can be read : 1
m
Remaining bytes that can be read : 0

5. Преобразуйте поток ввода файла для чтения

Также часто используется InputStreamReader для преобразования Входной поток в Читатель .

В этом примере показано, как преобразовать FileInputStream в BufferedReader и прочитать его построчно.

private static void readFileBetterInputStreamReader(String fileName) {

    try (BufferedReader br =
                 new BufferedReader(
                         new InputStreamReader(
                                 new FileInputStream(new File(fileName))))) {

        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

}

6. Входной поток файла – Чтение файла в Юникоде

В этом примере используется FileInputStream для чтения файла Unicode . Например:

Файл Юникода, содержащий несколько китайских символов, и каждый кодовый символ Юникода содержит два или более байта.

你好
我好
大家好

Мы можем использовать приведенный выше пример 3, чтобы прочитать файл Юникода и правильно распечатать их.

  private static void readFileBetterPerformance(String fileName) {

      try (FileInputStream fis = new FileInputStream(new File(fileName))) {

          // remaining bytes that can be read
          System.out.println("Remaining bytes that can be read : " + fis.available());

          // 8k a time
          byte[] bytes = new byte[8192];

          // reads 8192 bytes at a time, if end of the file, returns -1
          while (fis.read(bytes) != -1) {

              // convert bytes to string for demo

              // convert bytes unicode to string
              System.out.println(new String(bytes, StandardCharsets.UTF_8));

              System.out.println("Remaining bytes that can be read : " + fis.available());
          }
      } catch (IOException e) {
          e.printStackTrace();
      }

  }

Выход

Remaining bytes that can be read : 25
你好
我好
大家好
Remaining bytes that can be read : 0

Кроме того, мы также можем использовать пример 5 InputStreamReader для чтения и печати файла Юникода, по умолчанию InputStreamReader имеет кодировку UTF-8 по умолчанию.

Скачать Исходный Код

$клон git $клон git

$cd api/входной поток

Рекомендации

Оригинал: “https://mkyong.com/java/how-to-read-file-in-java-fileinputstream/”