-2

For some reason (new to Java), when I'm trying to read an Excel file from my resources folder, it shows that it is there, but when I use FileInputStream to read it I get a FileNotFound Exception. Any ideas?

Code:

public static void openExcelSheet() throws IOException {
    FileInputStream fileInputStream = null;
    if(applicationSettings.class.getResourceAsStream("/files/Employees.xlsx") != null) {
        System.out.println("File Found");
        fileInputStream = new FileInputStream("/files/Employees.xlsx");
    }else {
        System.out.println("File Not Found");
    }

    XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);

    //int numberOfSheets = workbook.getNumberOfSheets();
    System.out.println(workbook.getAllNames());

    workbook.close();
}

Here is the Output that I am receiving:

File Found
Exception in Application start method
java.lang.reflect.InvocationTargetException
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.base/java.lang.reflect.Method.invoke(Method.java:564)
 at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
 at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.base/java.lang.reflect.Method.invoke(Method.java:564)
 at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
Caused by: java.lang.RuntimeException: Exception in Application start method
 at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
 at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
 at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.io.FileNotFoundException: /files/Employees.xlsx (No such file or directory)
 at java.base/java.io.FileInputStream.open0(Native Method)
 at java.base/java.io.FileInputStream.open(FileInputStream.java:220)
 at java.base/java.io.FileInputStream.<init>(FileInputStream.java:158)
 at java.base/java.io.FileInputStream.<init>(FileInputStream.java:113)
 at applicationSettings.openExcelSheet(applicationSettings.java:32)
 at loginScreen.start(loginScreen.java:70)
 at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
 at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
 at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
 at java.base/java.security.AccessController.doPrivileged(Native Method)
 at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
 at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application loginScreen
Trey Carey
  • 143
  • 1
  • 8
  • is this maven?... – rogerdpack Aug 16 '18 at 21:51
  • can you print the error that you are receiving. – Nikhil Jain Aug 16 '18 at 21:53
  • 1
    `fileInputStream = new FileInputStream("/Employees.xlsx");` this suggests that the file resides at the root location of the current drive/mount ... is this the case? Where is the file stored in relationship to the execution context of the program? – MadProgrammer Aug 16 '18 at 21:55
  • Possible duplicate of [How to really read text file from classpath in Java](https://stackoverflow.com/questions/1464291/how-to-really-read-text-file-from-classpath-in-java) – sinclair Aug 16 '18 at 21:57

4 Answers4

1

Resources are not necessarily files; They could be stored as entries in a .jar archive. Even if they are stored as files in a directory structure of the file system, the working directory may not match the current working directory. You should use the InputStream returned by getResourceAsStream directly instead of trying to open a new one:

InputStream inputStream = applicationSettings.class.getResourceAsStream("/files/Employees.xlsx");
if (inputStream != null) {
    XSSFWorkbook workbook = new XSSFWorkbook(inputStream);

    //int numberOfSheets = workbook.getNumberOfSheets();
    System.out.println(workbook.getAllNames());

    workbook.close();
} else {
    System.out.println("Resource not found");
}
fabian
  • 80,457
  • 12
  • 86
  • 114
1

The problem seems to be some incorrect assumptions in your code:

if (applicationSettings.class.getResourceAsStream("/files/Employees.xlsx") != null) {
    System.out.println("File Found");
    fileInputStream = new FileInputStream("/files/Employees.xlsx");
} else {
    System.out.println("File Not Found");
}

So this is saying: "if I can find "Employees.xlsx" on the resource path, I can find it in the file system with the same path".

There are two incorrect assumptions here:

  1. You are assuming that since you found "Employees.xlsx" on the resource path will be in the file system at all. This is not a valid assumption:

    • The resource could be (in fact, typically will be) a member of a JAR file or a similar file.
    • The resource or the resource's container could have been downloaded on the fly to a temporary file, or into memory.
    • The resource could have been created on the fly; e.g. by a clever class loader that decrypts or uncompresses something else.
  2. You are assuming that "Employees.xlsx" will have the same resource path as file system path. This is pretty much guaranteed to not be the case. (It can only be the case if you put the root of the filesystem on the classpath ....)

I am not sure why you are trying to do this at all. Per @fabian's answer, POI allows you to open a spreadsheet from a InputStream. You should not need a FileInputStream here.

But in situations where you do need a FileInputStream for a resource on the resource path, the portable solution is to copy the resource to a temporary file, and then open a FileInputStream on the temporary file.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

Provided that your file is residing inside the project folder, here is the problem remove the slash from the front of the name

fileInputStream = new FileInputStream("Employees.xlsx");

should work then. If it is inside the files folder inside the project folder then

fileInputStream = new FileInputStream("files/Employees.xlsx");

Or you can provide the complete path to the file and that should work

fileInputStream = new FileInputStream("/users/myfolder/files/Employees.xlsx");
Nikhil Jain
  • 586
  • 6
  • 21
  • None of these Solutions are working, my file is as follows: Project/resources/files/Employees.xlsx My if statement says "File Found" But I get a FileNotFound Exception – Trey Carey Aug 16 '18 at 22:03
  • by project folder I meant the folder where your src of java files live – Nikhil Jain Aug 16 '18 at 22:05
  • could you provide the complete path to the file. You can do pwd on terminal when you are inside the files folder and it would tell you the complete path to the file – Nikhil Jain Aug 16 '18 at 22:05
  • Id give a complete path but it’s going to be on more then one machine so I’d like it wit the jar – Trey Carey Aug 16 '18 at 22:06
  • yeah then place the files folder inside your code folder. For eg if I am creating a java project say HelloWorld. Then HelloWorld would contain various folders such as src, lib, bin just like that you would be having one as well in that place your files folder – Nikhil Jain Aug 16 '18 at 22:09
  • once you do that all you need to do fileInputStream = new FileInputStream("files/Employees.xlsx"); – Nikhil Jain Aug 16 '18 at 22:10
0

I encountered the same issue today, which took me about two hours to partially figured it out. It was so annoying. Depending on how your class code is structured, Java does not allow you to read text file within the method definition. Try reading it in the main method, then take that FileInputStream object as input to your openExcelSheet() method. Let me know if it works :)

Kirk
  • 1
  • 2