В Java мы используем FileInputStream для чтения байтов из файла, такого как файл изображения или двоичный файл.
Темы
- Поток ввода файла – Чтение файла
- Поток ввода файла – Оставшиеся байты
- Поток ввода файлов – Более высокая производительность
- Поток ввода файла против потока ввода буфера
- InputStreamReader – Преобразование потока ввода файла в средство чтения
- 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/входной поток
Рекомендации
- Файловый поток ввода javadoc
- Буферизованный входной поток javadoc
- Поток вывода файла – Запись файла
- BufferedReader – Чтение файла
- Преобразовать входной поток для буферизованного чтения на Java
- Java – Чтение UTF-8 файл
Оригинал: “https://mkyong.com/java/how-to-read-file-in-java-fileinputstream/”