В 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/”