Overview
FileInputStream and FileOutputStream are used for reading and writing binary data (bytes) from files. They work with raw bytes rather than characters.
FileInputStream - Reading Files
Basic FileInputStream
import java.io.FileInputStream;
import java.io.IOException;
public class BasicFileInputStream {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("example.bin");
int byteData;
// Read bytes one by one
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData); // Convert to char for text files
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
System.err.println("Error closing file: " + e.getMessage());
}
}
}
}
FileInputStream with Try-with-Resources
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTryWithResources {
public static void main(String[] args) {
// Automatic resource management
try (FileInputStream fis = new FileInputStream("example.bin")) {
int byteData;
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData);
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Reading Bytes into Byte Array
import java.io.FileInputStream;
import java.io.IOException;
public class ReadByteArray {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("example.bin")) {
byte[] buffer = new byte[1024]; // 1KB buffer
int bytesRead;
// Read chunks of data
while ((bytesRead = fis.read(buffer)) != -1) {
// Process the bytes read
processBytes(buffer, bytesRead);
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
private static void processBytes(byte[] buffer, int bytesRead) {
System.out.println("Read " + bytesRead + " bytes");
// Process the bytes (e.g., convert to string, analyze, etc.)
String content = new String(buffer, 0, bytesRead);
System.out.print(content);
}
}
Reading Entire File into Byte Array
import java.io.FileInputStream;
import java.io.IOException;
public class ReadEntireFile {
public static byte[] readFile(String filename) throws IOException {
try (FileInputStream fis = new FileInputStream(filename)) {
// Get file size
long fileSize = fis.available();
byte[] fileData = new byte[(int) fileSize];
// Read entire file
fis.read(fileData);
return fileData;
}
}
public static void main(String[] args) {
try {
byte[] fileData = readFile("example.bin");
System.out.println("File size: " + fileData.length + " bytes");
// Convert to string if it's a text file
String content = new String(fileData);
System.out.println("File content: " + content);
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
FileOutputStream - Writing Files
Basic FileOutputStream
import java.io.FileOutputStream;
import java.io.IOException;
public class BasicFileOutputStream {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("output.bin");
String data = "Hello, World!";
// Convert string to bytes and write
byte[] bytes = data.getBytes();
fos.write(bytes);
System.out.println("Data written successfully");
} catch (IOException e) {
System.err.println("Error writing file: " + e.getMessage());
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
System.err.println("Error closing file: " + e.getMessage());
}
}
}
}
FileOutputStream with Try-with-Resources
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTryWithResources {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("output.bin")) {
String text = "This is a test message.\nSecond line.\nThird line.";
byte[] bytes = text.getBytes();
fos.write(bytes);
System.out.println("File written successfully");
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Append Mode vs Overwrite Mode
import java.io.FileOutputStream;
import java.io.IOException;
public class AppendModeExample {
public static void main(String[] args) {
// Overwrite mode (default)
try (FileOutputStream fos1 = new FileOutputStream("log.txt")) {
fos1.write("First entry\n".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
// Append mode (second parameter = true)
try (FileOutputStream fos2 = new FileOutputStream("log.txt", true)) {
fos2.write("Second entry (appended)\n".getBytes());
fos2.write("Third entry (appended)\n".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Writing Byte Arrays in Chunks
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteByteChunks {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("largefile.bin")) {
byte[] data = generateLargeData();
// Write in chunks of 1KB
int chunkSize = 1024;
for (int i = 0; i < data.length; i += chunkSize) {
int end = Math.min(data.length, i + chunkSize);
fos.write(data, i, end - i);
System.out.println("Written " + end + " bytes");
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
private static byte[] generateLargeData() {
// Generate 10KB of data
byte[] data = new byte[10 * 1024];
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (i % 256);
}
return data;
}
}
Practical Examples
1. File Copy Utility
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopyUtility {
public static void copyFile(String sourceFile, String destFile) throws IOException {
try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(destFile)) {
byte[] buffer = new byte[4096]; // 4KB buffer
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
System.out.println("File copied successfully: " + sourceFile + " -> " + destFile);
}
}
public static void main(String[] args) {
try {
copyFile("source.bin", "destination.bin");
} catch (IOException e) {
System.err.println("Copy failed: " + e.getMessage());
}
}
}
2. Image File Operations
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ImageFileOperations {
// Read image file and create a copy
public static void copyImage(String sourceImage, String destImage) throws IOException {
try (FileInputStream fis = new FileInputStream(sourceImage);
FileOutputStream fos = new FileOutputStream(destImage)) {
byte[] buffer = new byte[8192]; // 8KB buffer for images
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
System.out.println("Image copied: " + sourceImage + " -> " + destImage);
}
}
// Check if file is an image by reading header
public static boolean isImageFile(String filename) {
try (FileInputStream fis = new FileInputStream(filename)) {
byte[] header = new byte[8];
int bytesRead = fis.read(header);
if (bytesRead < 8) return false;
// Check for common image file signatures
return isJPEG(header) || isPNG(header) || isGIF(header);
} catch (IOException e) {
return false;
}
}
private static boolean isJPEG(byte[] header) {
return (header[0] == (byte) 0xFF && header[1] == (byte) 0xD8);
}
private static boolean isPNG(byte[] header) {
return (header[0] == (byte) 0x89 && header[1] == (byte) 0x50 &&
header[2] == (byte) 0x4E && header[3] == (byte) 0x47);
}
private static boolean isGIF(byte[] header) {
return (header[0] == (byte) 'G' && header[1] == (byte) 'I' &&
header[2] == (byte) 'F');
}
public static void main(String[] args) {
try {
String imageFile = "photo.jpg";
if (isImageFile(imageFile)) {
System.out.println(imageFile + " is a valid image file");
copyImage(imageFile, "photo_copy.jpg");
} else {
System.out.println(imageFile + " is not a recognized image file");
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
3. Binary Data Logger
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
public class BinaryLogger {
private static final String LOG_FILE = "application.log";
public static void logEvent(String event) {
try (FileOutputStream fos = new FileOutputStream(LOG_FILE, true)) {
// Add timestamp
String timestamp = new Date() + " - " + event + "\n";
byte[] data = timestamp.getBytes();
fos.write(data);
fos.flush(); // Ensure data is written immediately
} catch (IOException e) {
System.err.println("Logging failed: " + e.getMessage());
}
}
public static void readLog() {
try (FileInputStream fis = new FileInputStream(LOG_FILE)) {
byte[] buffer = new byte[1024];
int bytesRead;
System.out.println("=== Application Log ===");
while ((bytesRead = fis.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, bytesRead));
}
} catch (IOException e) {
System.err.println("Error reading log: " + e.getMessage());
}
}
public static void main(String[] args) {
// Log some events
logEvent("Application started");
logEvent("User logged in");
logEvent("File processed successfully");
logEvent("Application shutdown");
// Read and display log
readLog();
}
}
4. File Encryption/Decryption Example
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class SimpleFileEncryption {
// Simple XOR encryption/decryption
public static void processFile(String inputFile, String outputFile, byte key) throws IOException {
try (FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// XOR each byte with the key
for (int i = 0; i < bytesRead; i++) {
buffer[i] = (byte) (buffer[i] ^ key);
}
fos.write(buffer, 0, bytesRead);
}
}
}
public static void main(String[] args) {
byte encryptionKey = 0x55; // Simple key
try {
// Encrypt file
processFile("original.txt", "encrypted.bin", encryptionKey);
System.out.println("File encrypted successfully");
// Decrypt file (same operation with same key)
processFile("encrypted.bin", "decrypted.txt", encryptionKey);
System.out.println("File decrypted successfully");
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Advanced Features
Available() Method
import java.io.FileInputStream;
import java.io.IOException;
public class AvailableExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("example.bin")) {
// Check how many bytes are available to read
int availableBytes = fis.available();
System.out.println("Available bytes: " + availableBytes);
if (availableBytes > 0) {
byte[] data = new byte[availableBytes];
fis.read(data);
System.out.println("Read " + data.length + " bytes");
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Skip() Method
import java.io.FileInputStream;
import java.io.IOException;
public class SkipExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("largefile.bin")) {
// Skip first 1024 bytes
long skipped = fis.skip(1024);
System.out.println("Skipped " + skipped + " bytes");
// Read the rest
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// Process data starting from byte 1025
processData(buffer, bytesRead);
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
private static void processData(byte[] data, int length) {
// Process the data
System.out.println("Processing " + length + " bytes");
}
}
Error Handling Best Practices
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class RobustFileOperations {
public static boolean safeFileCopy(String source, String destination) {
// Validate inputs
if (source == null || destination == null) {
System.err.println("Source and destination cannot be null");
return false;
}
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(destination)) {
// Check if source file is readable
if (fis.available() == 0) {
System.err.println("Source file is empty or not accessible");
return false;
}
byte[] buffer = new byte[8192];
int bytesRead;
long totalBytes = 0;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
totalBytes += bytesRead;
// Optional: Add progress reporting for large files
if (totalBytes % (1024 * 1024) == 0) { // Every 1MB
System.out.println("Copied " + (totalBytes / (1024 * 1024)) + " MB");
}
}
System.out.println("Copy completed: " + totalBytes + " bytes copied");
return true;
} catch (IOException e) {
System.err.println("Copy failed: " + e.getMessage());
return false;
}
}
public static void main(String[] args) {
boolean success = safeFileCopy("source.bin", "destination.bin");
if (success) {
System.out.println("File copy operation completed successfully");
} else {
System.out.println("File copy operation failed");
}
}
}
Performance Considerations
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class PerformanceTest {
public static void testBufferSizes(String filename) {
int[] bufferSizes = {128, 1024, 4096, 8192, 16384};
for (int bufferSize : bufferSizes) {
long startTime = System.currentTimeMillis();
try (FileInputStream fis = new FileInputStream(filename);
FileOutputStream fos = new FileOutputStream("copy_" + bufferSize + ".bin")) {
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
System.err.println("Error with buffer size " + bufferSize + ": " + e.getMessage());
continue;
}
long endTime = System.currentTimeMillis();
System.out.println("Buffer size " + bufferSize + ": " + (endTime - startTime) + "ms");
}
}
public static void main(String[] args) {
testBufferSizes("largefile.bin");
}
}
Key Points to Remember
- FileInputStream is for reading raw bytes from files
- FileOutputStream is for writing raw bytes to files
- Always close streams using try-with-resources
- Use appropriate buffer sizes for better performance
- Handle exceptions properly - IOException is common
- Use append mode when you want to add to existing files
- Flush output streams when immediate writing is needed
- Binary files require byte-level operations, not character operations
These classes are fundamental for binary file operations in Java and are widely used for working with images, videos, documents, and any non-text files.