简体   繁体   中英

Java Swing Gui is not able to read data from the file inside the runnable jar

Okay, so I'm having a problem where once I export my Java Swing project into a runnable jar file one part of the feature I coded does not function at all. Which is to read the file "TryndaUpdate101720.tsv". It works fine when I test it out in IDE eclipse but once it's exported it's not able to function as in the test environment.

I have looked up this problem and couldn't find any solution. There is another way I can make it so it read the "TryndaUpdate101720.tsv" but it's not user friendly because I have to include the "TryndaUpdate101720.tsv" outside of the runnable jar file and have to take input from the user to get the path of it. Which I really don't want to do.

Implementation of reading the file code:

allRows = parser.parseAll(new FileReader(this.getClass().getResource("/sim/resources/TryndaUpdate101720.tsv").getPath()));

This is the error I'm getting when I run the exported runnable jar file. I have bolded the error to indicate that is the file path where the code break. My guess is because of "!" in the file path.

java.io.FileNotFoundException: **file:\C:\Users\ssimr\Downloads\TryndaMatchUpGui.jar!\sim\resources\TryndaUpdate101720.tsv (The filename, directory name, or volume label syntax is incorrect)**
    at java.base/java.io.FileInputStream.open0(Native Method)
    at java.base/java.io.FileInputStream.open(FileInputStream.java:211)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:153)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:108)
    at java.base/java.io.FileReader.<init>(FileReader.java:60)
    **at sim.gui.WhichChamp.getChampFromTSV(WhichChamp.java:217)**
    at sim.gui.Expertimentgui$4.mouseClicked(Expertimentgui.java:368)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6617)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6379)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4990)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4822)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4557)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2769)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4822)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)

You will need to get the resource as a Stream to read the file from your JAR. Here is an example to read a text file as a stream. Also, make sure your file path is correct because that can be a problem.

//static URL url = ClassName.class.getClassLoader().getResource("/sim/resources/TryndaUpdate101720.tsv");
//InputStreamReader file = new InputStreamReader(url.openStream());
static InputStream in = ClassName.class.getResourceAsStream("/sim/resources/TryndaUpdate101720.tsv");

public static void readTxtFile(String content) {
        BufferedReader br;
        try {
            //FileReader file = new FileReader(filename);
            //InputStreamReader file = new InputStreamReader(url.openStream());
            //System.out.println(file.getAbsolutePath());
            in = Thread.currentThread().getContextClassLoader().getResourceAsStream("TryndaUpdate101720.tsv");
            br = new BufferedReader(new InputStreamReader(in));
            
            String line = br.readLine();
            int i = 0;
            while(line != null) {
                if(line.equals(content)) {
                    System.out.println("Expected input equals actual text!");
                    break;
                }
                line = br.readLine();
                i++;
            }
            
            br.close();
        } catch (Exception e) {
            //System.out.println("Exception occurred in readTxtFile.");
            e.printStackTrace();
        }
}

See also this

Depends on what kind of build tools you are using. The file you want to access , may not included in the jar or included but in a different location.

Eclipse and some IDE will run the app from the project location, so it will able to run without issue.

Check documents for you tool , ant, maven, gradle etc for how to include resources in the jar.

Thanks to @Pranav Amarnath I was able to resolve my problem. So instead of using FileReader I used BufferedReader with getResourceAsStream to get the file inside the jar file.

Before:

allRows = parser.parseAll(new FileReader(this.getClass().getResource("/sim/resources/TryndaUpdate101720.tsv").getPath()));

After:

InputStream in = getClass().getResourceAsStream("/sim/resources/TryndaUpdate101720.tsv"); 
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
allRows = parser.parseAll(reader);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM