【问题标题】:Reading CSV file return java.io.FileNotFoundException:读取 CSV 文件返回 java.io.FileNotFoundException:
【发布时间】:2017-01-01 11:04:57
【问题描述】:

我正在尝试从应用程序中读取 csv 文件。但我得到java.io.FileNotFoundException:。下面是我的csv阅读代码。

    String constantURL = AppConst.INTERNAL_ASSETS_CONFIG_ROOT_URL + "whitelist/RMWhitelist.csv";
    logger.info("constantURL >  " + constantURL);

    BufferedReader br = null;
    String line = "";
    String cvsSplitBy = ",";
    try{         

        br = new BufferedReader(new InputStreamReader(new FileInputStream(constantURL)));      
        while ((line = br.readLine()) != null) {
           String[] country = line.split(cvsSplitBy);
           System.out.println("Country [code= " + country[0] + " , name=" + country[1] + "]");
        }
    }catch(Exception e){
        e.printStackTrace();
    }

下面是我得到的错误。

 INFO: constantURL >  http://localhost:7001/shops/config/whitelist/milRMWhitelist.csv
 java.io.FileNotFoundException: http:\localhost:7001\app\config\whitelist\RMWhitelist.csv (The filename, directory name, or volume label syntax is incorrect)

为什么会出现此错误? CSV 文件在路径中可用。

更新

以下是我在另一个项目中使用的现有代码之一。这工作正常。但是相同的代码在这个新项目中不起作用。得到 F.N.F 错误。这如何区分文件输入流是 URL 还是文件路径?

final String file = this.httpRequestPoster.sendGetRequest(AppUrlConst.CONFIG_URL + "other.csv", "");
    Reader reader = new StringReader(file);
    final CSVReaderBuilder<UpgradeVO> customerVOCSVReaderBuilder = new CSVReaderBuilder<UpgradeVO>(reader);
    customerVOCSVReaderBuilder.strategy(CSVStrategy.UK_DEFAULT);
    CSVReader<UpgradeVO> customerVOCSVReader = customerVOCSVReaderBuilder.entryParser(new UpgradeParser()).build();
    Iterator<UpgradeVO> customerVOIterator = customerVOCSVReader.iterator();
    while (customerVOIterator.hasNext()) {
        UpgradeVO upgradeVO = customerVOIterator.next();
        logger.info(UpgradeVO.getServiceId());
    }

【问题讨论】:

  • 您的文件是否在错误消息或类路径中显示的路径中可用?
  • 您需要确定流的来源。如果源字符串是文件位置而不是 http url,则更新后的代码将不起作用。
  • @daotan 但这是我现有的代码,对于 URL 和文件路径都可以正常工作,无需进行任何调整。
  • @everalian 我不知道您如何初始化“AppUrlConst.CONFIG_URL”变量,但如果您的驱动器中有 csv 文件,请尝试使用“file:///C:/somedir/”协议。跨度>
  • @daotan 在我的开发中它会进入耳朵。所以 URL 是http://localhost:7001/shops/config/whitelist/milRMWhitelist.csv。但在生产中,它将从服务器位置获取。此行为在属性文件中进行控制。所有这些在其他项目中都可以正常工作。这是我的问题。

标签: java csv io


【解决方案1】:

您将代表 URL 的字符串传递给 FileInputStream。 FileInputStream 需要一个指向文件系统的文件名。因此,您的方法不起作用!

换句话说:通过包含主机 IP 地址和端口号,您的字符串不再是“只是一个文件名”。

因此有两种选择:

  1. 如果你真的想传递一个 URL,那么你需要使用一个真正的 URL 对象,并使用它的 openStream() 方法。含义:您从字符串创建 FileInputStream;您创建一个 URL 对象;然后在该对象上调用 openStream() 以从该流中读取
  2. 你修改你的字符串就是:一个“平面”文件名;没有任何 IP 地址或端口号。

【讨论】:

  • 怎么做?举个例子?我试过这个final String file = this.httpRequestPoster.sendGetRequest(constantURL, ""); 仍然是同样的错误。当我打印file 的输出时,我看到了文件的内容。但仍然有相同的 F.N.F 错误
【解决方案2】:

您正在将 FileInputStreams 与 HTTP URL 混合

使用一个或另一个

例如

 InputStream input = new URL(constantUrl).openStream();

 br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));

【讨论】:

  • 这个路径,我本地开发的时候是url路径。但是在生产时它是从磁盘读取的。但是我的代码应该保持不变来处理 url 和磁盘 CSV 文件。
  • 在这种情况下,也许你应该检查 url 字符串来决定使用哪一个
  • @everalian 您可以使用类似if(new File(filePath).exists()){...} 的方式检查路径是否为文件
  • @ScaryWombat 我更新了问题区域中的代码。为什么该代码适用于 URL 和文件路径?它如何处理不同的输入流?该代码在我的新项目中不起作用。我不知道为什么。这就是我想重写这段新代码的原因。
  • @Titus 请参考我的问题更新区域。该代码在我的另一个代码中。那个适用于 URL 或文件路径。我从来没有判断它是 URL 还是文件路径的逻辑
【解决方案3】:

根据您的 cmets 和对您问题的更新,我认为这会起作用:

String constantURL = AppConst.INTERNAL_ASSETS_CONFIG_ROOT_URL + "whitelist/RMWhitelist.csv";
File file = new File(constantURL);
String cvsSplitBy = ",";
try(BufferedReader br = new BufferedReader(new InputStreamReader(file.exists()?new FileInputStream(file): new URL(constantURL).openStream()));){    
    for (String line; (line = br.readLine()) != null;) {
       String[] country = line.split(cvsSplitBy);
       System.out.println("Country [code= " + country[0] + " , name=" + country[1] + "]");
    }
}catch(Exception e){
    e.printStackTrace();
}

重要的部分是file.exists() ? new FileInputStream(file) : new URL(constantURL).openStream(),它检查constantURL 是否是本地文件系统上的有效文件路径。如果是,它会打开一个FileInputStream,如果不是,它会尝试打开一个 url 连接。

【讨论】:

    【解决方案4】:

    我不知道你是如何声明 AppConst.INTERNAL_ASSETS_CONFIG_ROOT_URL 变量的

    尝试使用 file:/// 协议来设置文件的值 例子

    URL urlFile = new URL("file:///C:/whitelist/RMWhitelist.csv");
    URL urlHttp = new URL("http://http://localhost:7001/shops/config/");
    

    应该可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-28
      • 2013-07-12
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 2017-02-06
      • 1970-01-01
      相关资源
      最近更新 更多