FileInputStream
In short: A byte stream for raw, unbuffered reading of a file — reads the file byte by byte, regardless of whether the content is text, an image, or any other binary format.
In more detail: Because a pure byte stream works with no intermediate buffer, it’s slow for many small read accesses — in practice, it’s therefore usually combined with a buffered wrapper. For pure text, a character-based reader (which correctly accounts for character encoding) is usually the more suitable choice than a raw byte stream.
In Depth
The core of a FileInputStream is deliberately minimal: it offers exactly one operation — read the next byte (or a block of bytes at once) — with no interpretation whatsoever of what those bytes mean. A byte has no “character set”, no “format”, it’s simply a number between 0 and 255. This is exactly what makes this stream universally usable for ANY kind of file, whether text, image, audio, or a proprietary binary format.
try (FileInputStream fis = new FileInputStream("image.png")) {
int nextByte;
while ((nextByte = fis.read()) != -1) {
process(nextByte);
}
}The return value -1 from a call to read() typically signals the end of the file (EOF) — a classic example of a error code as a return value, which, however, doesn’t mean an error at all here, but a normal, expected state (end of file reached).
The reason for the “unbuffered” characterisation: every single call to read() can (depending on the implementation) actually pass all the way through to the operating system, to physically fetch the next byte from the storage device. For millions of individual byte reads, this overhead adds up massively — which is why a FileInputStream is in practice almost always wrapped in a BufferedReader or a buffered byte stream, which internally reads larger blocks at once and serves individual requests from them.
For pure text content, a FileInputStream is rarely the right choice, because it doesn’t know how bytes should be converted into characters (which character encoding applies) — an “é” can consist of one or several bytes depending on the encoding (UTF-8, Latin-1, …). A character-based reader automatically handles this conversion correctly, while a raw byte stream would instead pass the bytes on unchanged and potentially wrongly interpreted.
See also: I/O Streams, BufferedReader, FileOutputStream