Core Java

Java getResourceAsStream vs FileInputStream

Reading files is a common task in Java development, and understanding the various methods available can help us choose the most appropriate one for our use case. This article will explore three different approaches: getResourceAsStream vs FileInputStream, and Files.newInputStream(). We will compare their usage, discuss when each method is most suitable, and provide code examples to illustrate their differences.

1. getResourceAsStream() Method

The getResourceAsStream() method is part of the Class and ClassLoader classes and is used to load resources (such as files) that are packaged within an application’s classpath. This method is particularly useful when dealing with files bundled within JAR files or located in the src/main/resources directory of a project. Some use cases include:

  • Accessing configuration files, properties, or other resources packaged within an application’s JAR or classpath.
  • Loading files in a platform-independent way, without worrying about absolute file paths.

Advantages:

  • Classpath Resources: Ideal for reading files that are bundled with our application’s resources.
  • Portability: Works seamlessly across different environments (e.g., JAR, WAR).
  • No Absolute Paths Required: Since it reads from the classpath, it avoids the need for hardcoding absolute paths.

Disadvantages:

  • Limited to Classpath: It can only access files within the classpath, making it unsuitable for files outside the classpath.
public class ResourceLoaderExample {

    public static void main(String[] args) {
        // Load the resource using getResourceAsStream
        try (InputStream inputStream = ResourceLoaderExample.class.getResourceAsStream("/config.properties"); 
                
                
           BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            System.out.println("Error reading file" + e);
        }
    }
}

In this example:

  • The getResourceAsStream("/config.properties") method loads the config.properties file from the classpath.
  • The resource is read as an InputStream, which is then wrapped in a BufferedReader for line-by-line reading.
  • Since the resource is part of the classpath, this method works seamlessly whether the application is run from an IDE, a JAR file, or a web container.

Note: The config.properties file should be located in the application’s classpath, typically in the src/main/resources folder. This ensures that it can be accessed using the getResourceAsStream() method.

2. FileInputStream Class

The FileInputStream class is a basic file reading mechanism that operates directly on files located on the file system. Unlike getResourceAsStream(), FileInputStream requires an absolute or relative path to the file on the disk. Use cases include:

  • Reading files located outside the classpath, such as in the file system.
  • Situations where the file location is known and can be referenced directly.
public class FileInputStreamExample {

    public static void main(String[] args) {
        // File path to be read
        String filePath = "/Users/path/to/config.properties";

        // Load the file using FileInputStream
        try (FileInputStream fileInputStream = new FileInputStream(filePath);
                
             BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream))) {

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
        }
    }
}

This example reads a config.properties file from a directory using FileInputStream.

  • FileInputStream requires a direct file path, which means the file must exist on the disk where the application is running.
  • This method is less flexible than getResourceAsStream() because it doesn’t handle files packaged within JARs or classpaths.

Advantages:

  • Filesystem Access: We can access any filesystem file, provided we have the correct path and permissions.
  • Simplicity: Straightforward to use for reading files from disk.

Disadvantages:

  • Performance: Can be less efficient in terms of memory and performance compared to modern alternatives.
  • Error-Prone: Requires careful handling of absolute paths and closing resources.

3. Files.newInputStream() Method

The Files.newInputStream() method is part of the NIO (New I/O) package introduced in Java 7. It offers a more modern and flexible way to read files, with better memory management and performance compared to FileInputStream. Use cases include:

  • Reading files in a more efficient and modern way.
  • Handling large files or scenarios where non-blocking I/O is beneficial.
  • Situations where enhanced features of the NIO package (like file attributes and better exception handling) are needed.
public class FilesNewInputStreamExample {

public static void main(String[] args) {
        // File path to be read
        Path filePath = Paths.get("/Users/path/to/config.properties");

        // Load the file using Files.newInputStream
        try (InputStream inputStream = Files.newInputStream(filePath);
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
        }
    }
}

In this example, the Files.newInputStream() method is used to read the config.properties file which offers better performance and flexibility compared to FileInputStream.

  • Files.newInputStream() provides a more modern API for reading files compared to FileInputStream.
  • It is often preferred because of its improved performance, better memory management, and the added benefits of working with NIO features like Path.

Advantages:

  • Memory Efficiency: More efficient in terms of memory usage compared to FileInputStream.
  • Performance: Offers better performance, especially with large files.
  • Flexibility: Provides more options for configuring file access, such as specifying file attributes or options.

Disadvantages:

  • Complexity: Slightly more complex than FileInputStream, though the benefits usually outweigh this drawback.

3.1 Why Files.newInputStream() Is Recommended Over FileInputStream

While FileInputStream is a tried and trusted method for reading files, Files.newInputStream() is generally recommended due to its superior memory management and performance. Here are some reasons why:

  • Improved Performance: Files.newInputStream() is optimized for better performance, especially with large files, by leveraging the java.nio.file package’s more modern and efficient I/O mechanisms.
  • Memory Efficiency: Files.newInputStream() uses less memory compared to FileInputStream, which can be crucial when working with large files or resource-constrained environments.
  • Enhanced Flexibility: Files.newInputStream() allows us to specify file attributes and options, giving us greater control over file access.

4. Comparison Summary (getResourceAsStream vs FileInputStream)

Feature/AspectgetResourceAsStream()FileInputStreamFiles.newInputStream()
Classpath SupportYesNoNo
JAR CompatibilityYesNoNo
FlexibilityHigh (classpath resources)Low (requires file system path)Medium (file system with NIO advantages)
PerformanceDepends on use caseBasic, potentially less efficientDepends on the use case
Modern APINo (older, classpath-specific)No (older, file system-specific)Yes (NIO package with additional features)
Use CaseBundled resources, configuration filesFile system filesModern file handling, large files, performance

5. Conclusion

Choosing the right file reading method in Java depends on your specific use case. If we are dealing with resources bundled within our application’s classpath, getResourceAsStream() is the way to go. For direct file system access, FileInputStream is a straightforward but somewhat outdated choice. However, for modern applications, Files.newInputStream() is often the preferred method due to its enhanced performance, flexibility, and alignment with the NIO package.

6. Download the Source Code

This article covered getResourceAsStream() vs FileInputStream methods in Java.

Download
You can download the full source code of this example here: Java getresourceasstream vs fileinputstream

Omozegie Aziegbe

Omos Aziegbe is a technical writer and web/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button