【问题标题】:When i run jar file i can't read files correctly当我运行 jar 文件时,我无法正确读取文件
【发布时间】:2021-05-24 06:31:10
【问题描述】:

我编写了一个代码,通过读取 csv 文件中的信息,根据这些城市的区域创建城市和区域。 csv 文件长 81 行。它包含来自土耳其 81 个城市的一些信息。我想将此 csv 文件中的每一行添加到字符串数组中,然后将其打印在屏幕上。我还想将使用此信息创建的区域对象保留在 Region 数组中。然后,我想从这个区域数组中打印区域名称。土耳其有 7 个地区。

编辑:我尝试从 txt 文件而不是 csv 读取数据。我再次遇到同样的错误。另外,我正在尝试在 Windows 上运行 jar。我在 windows(10) 上收到这些错误,但是当我尝试在 ubuntu 上运行程序时,我没有。

代码在 Eclipse 上看起来工作正常,它提供了我想要的输出。

output

我想用可执行的 jar 文件运行这个程序。所以,我通过 Eclipse 将项目导出为可运行的 jar,但是当我尝试在 cmd 上运行这个 jar 文件时,键入:

java -jar myjar.jar

我收到这样的错误。

error

我不知道为什么会出现这个错误。 CSV文件如下。

CSV

当我用eclipse逐步运行程序时,我找不到任何可能导致错误的东西。你怎么看这个问题?

我可能在哪里犯了错误?

这是我所有的类定义。

主类

import java.io.FileNotFoundException;

public class Launcher {

    public static void main(String[] args) throws FileNotFoundException {

        String[] infoArray = ArrayCreator.createInfoArray("Cities.csv");
        for (String info : infoArray) {
            System.out.println(info);
        }
        System.out.println();
        Region[] regionArray = ArrayCreator.createRegionArray(infoArray);
        for (Region region : regionArray) {
            System.out.println(region.getName());
        }

    }

}

数组创建类

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ArrayCreator {

    private static int capacityDetector(String fileName) throws FileNotFoundException {
        Scanner scanner1 = new Scanner(new File(fileName));
        int count = 0;
        while (scanner1.hasNext()) {
            count++;
            scanner1.nextLine();
        }
        scanner1.close();
        return count;
    }

    public static String[] createInfoArray(String fileName) throws FileNotFoundException {

        int capacity = capacityDetector(fileName);
        Scanner scanner2 = new Scanner(new File(fileName));
        String[] returnArray = new String[capacity];

        int index = 0;
        while (scanner2.hasNextLine()) {
            returnArray[index] = scanner2.nextLine();
            index++;
        }
        scanner2.close();
        return returnArray;
    }

    /**
     * This method creates an array which contains all the region.
     * 
     * @param infoArray String array about the cities and their regions information.
     *                  Elements must be in the CSV format and should be compatible
     *                  with other parts of the project.
     * @return an array which contains all the regions.
     */
    public static Region[] createRegionArray(String[] infoArray) {

        // infoArray is actually city information array. So there may be too many
        // times for the same region information. We just want to create only one region
        // for the same regions. So, we must do not create the regions that are already
        // exist.

        int index = 0;
        Region[] regionArr = new Region[index + 1];
        regionArr[index] = new Region(infoArray[0]); // We are sure that the region in the first information was not
                                                        // created before.
        for (int i = 1; i < infoArray.length; i++) {
            String info = infoArray[i];
            String[] splitted_info = info.split(",");
            boolean found = false;
            for (Region region : regionArr) {
                String newRegionName = splitted_info[3];
                String currRegionName = region.getName();

                if (newRegionName.equals(currRegionName)) {
                    found = true;
                    break;

                }
            }
            if (!found) { // if the object of this region was not created before.
                index++;
                Region new_region = new Region(info); // We dont know how many regions are there and we work with
                                                        // arrays. So we have to increase the array size manually.
                Region[] temp = new Region[index + 1];

                for (int j = 0; j < regionArr.length; j++) {
                    temp[j] = regionArr[j];
                }
                temp[index] = new_region;
                regionArr = temp;

            }
        }
        return regionArr;

    }

}

区域类


public class Region {
    private int ID;
    private String name;
    private City[] cities;

    /**
     * Constructor for Region Class Object.
     * 
     * @param name Name of the region.
     */
    public Region(String info) {
        String[] splitted_info = info.split(",");
        this.ID = Integer.parseInt(splitted_info[2]);
        this.name = splitted_info[3];

    }

    /**
     * A helper method to find the number of the cities which are in this region.
     * 
     * @param allCities An array which contains all the cities.
     * @return An integer which is the number of the cities in this region.
     *
     */
    private int findCitiesOfRegionArraySize(City[] allCities) {
        int returnInt = 0;
        for (City aCity : allCities) {
            if (aCity.getRegion().getName().equals(this.name)) {
                returnInt++;
            }
        }
        return returnInt;

    }

    /**
     * Creates the City array of a region.
     * 
     * @param allCities An array which contains all the cities.
     * @return City array that contains all the cities in this region.
     */
    public void createCitiesOfRegion(City[] allCities) {
        City[] cityArray = new City[findCitiesOfRegionArraySize(allCities)];
        int index = 0;
        for (City aCity : allCities) {
            if (aCity.getRegion().getName() == this.name) {
                cityArray[index] = aCity;
                index++;
            }
        }

        this.cities = cityArray;
    }

    public int getID() {
        return ID;
    }

    public String getName() {
        return name;
    }

    public City[] getCities() {
        return cities;
    }

}

城市等级


public class Region {
    private int ID;
    private String name;
    private City[] cities;

    /**
     * Constructor for Region Class Object.
     * 
     * @param name Name of the region.
     */
    public Region(String info) {
        String[] splitted_info = info.split(",");
        this.ID = Integer.parseInt(splitted_info[2]);
        this.name = splitted_info[3];

    }

    /**
     * A helper method to find the number of the cities which are in this region.
     * 
     * @param allCities An array which contains all the cities.
     * @return An integer which is the number of the cities in this region.
     *
     */
    private int findCitiesOfRegionArraySize(City[] allCities) {
        int returnInt = 0;
        for (City aCity : allCities) {
            if (aCity.getRegion().getName().equals(this.name)) {
                returnInt++;
            }
        }
        return returnInt;

    }

    /**
     * Creates the City array of a region.
     * 
     * @param allCities An array which contains all the cities.
     * @return City array that contains all the cities in this region.
     */
    public void createCitiesOfRegion(City[] allCities) {
        City[] cityArray = new City[findCitiesOfRegionArraySize(allCities)];
        int index = 0;
        for (City aCity : allCities) {
            if (aCity.getRegion().getName() == this.name) {
                cityArray[index] = aCity;
                index++;
            }
        }

        this.cities = cityArray;
    }

    public int getID() {
        return ID;
    }

    public String getName() {
        return name;
    }

    public City[] getCities() {
        return cities;
    }

}

【问题讨论】:

  • 关于,“我不认为代码有问题” -- 我不确定我们如何在没有您的情况下开始验证或接受这一点显示可运行的代码,如果我站在你的立场上,在找到原因和解决方案之前,我不会做出这样的假设。最适合您将代码缩减到最小的minimal reproducible example,并将其作为代码格式的文本发布在您的问题中。
  • "weather query application" 'query' 部分表明代码正在进行远程调用,这可能导致异常。请确保发布为edit 的MRE(如@HovercraftFullOfEels 所建议)在每个catch 中都包含对printStackTrace() 的调用。
  • 可能卡在了无限循环中......
  • 感谢您的更新。它仍然不是minimal reproducible example,不是我们可以测试的代码,但比以前的要好一些。在您可以创建重现问题的 MRE 之前,请考虑在整个程序中记录日志或更多 println 语句,以至少确定问题的位置。
  • “jar 文件.. 无法正确读取文件” 这是因为 Jar 文件不包含我们可以用作 File 的内容。应用程序资源在部署时将成为嵌入式资源,因此明智的做法是立即开始访问它们。 embedded-resource 必须通过 URL 而不是文件访问。请参阅info. page for embedded resource 了解如何形成 URL。 -- 很幸运你改变了标题,因为仍然没有 MRE(正如@HovercraftFullOfEels 所指出的那样),所以人们不太可能尝试复制。

标签: java eclipse swing executable-jar embedded-resource


【解决方案1】:

当我使用 BufferedReader 从 CSV 文件中读取数据而不是使用 Scanner 读取数据时,我的问题得到了解决。另外,我通过将必要的文件(csv 文件)放在名为 resource 的包中,将它们用作嵌入资源。

我用这个来检测容量

private static int capacityDetector(String filename) throws IOException {
        InputStream in = new FileIO().getClass().getResourceAsStream(filename);
        @SuppressWarnings("resource")
        BufferedReader csv = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
        int capacity = 0;
        @SuppressWarnings("unused")
        String line;
        while ((line = csv.readLine()) != null) {
            capacity++;
        }
        return capacity;

    }

而不是

private static int capacityDetector(String fileName) throws FileNotFoundException {
        Scanner scanner1 = new Scanner(new File(fileName));
        int count = 0;
        while (scanner1.hasNext()) {
            count++;
            scanner1.nextLine();
        }
        scanner1.close();
        return count;
    }

我使用这段代码来创建信息数组

public static String[] createInfoArray(String filename) throws IOException {
        InputStream in = new FileIO().getClass().getResourceAsStream(filename);
        @SuppressWarnings("resource")
        BufferedReader csv = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
        int capacity = capacityDetector(filename);
        String[] infoArray = new String[capacity];
        for (int i = 0; i < capacity; i++) {
            infoArray[i] = csv.readLine();
        }
        return infoArray;

    }

而不是

public static String[] createInfoArray(String fileName) throws FileNotFoundException {

        int capacity = capacityDetector(fileName);
        Scanner scanner2 = new Scanner(new File(fileName));
        String[] returnArray = new String[capacity];

        int index = 0;
        while (scanner2.hasNextLine()) {
            returnArray[index] = scanner2.nextLine();
            index++;
        }
        scanner2.close();
        return returnArray;
    }

最后,我在 main 中调用了这些方法

String[] cityInfoArray = FileIO.createInfoArray("/resources/Cities.csv");

String[] forecastInfoArray = FileIO.createInfoArray("/resources/WeeklyForecast.csv");

现在,我可以通过双击 jar 文件毫无问题地运行我的程序。

【讨论】:

  • “我应该回答我自己的问题吗?” 很高兴你们俩都解决了问题并且找到了该问题的答案。 :) 请在网站允许时accept the answer
  • 我是 stackoverflow 的新手 :) 事实上,这是我在 stackoverflow 中提出的第一个问题。即使这是我在互联网上提出的第一个问题。因此,我可能在提出问题并试图将问题变为 MRE 时遇到了一些麻烦。但我认为这也教会了我一些东西。这样一来,我想从现在开始我提出的任何问题都会得到更快的答复。再次感谢。健康的日子!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 2022-06-14
相关资源
最近更新 更多