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.