【问题标题】:A file equals content of website?一个文件等于网站的内容?
【发布时间】:2013-09-04 15:20:05
【问题描述】:

我不知道如何将特定文件的内容与网站的内容进行比较。

这是我用来检查的代码,如果它等于:

 private static boolean equals() {
    try {
        return new String(Files.readAllBytes(Paths.get(filePath))).equals(getFile());
    } catch (Exception e) {
        return false;
    }
}

文件路径:

private static final String filePath = "test.txt";

getFile():

private static String getFile() {
    try {
        URL pageURL = new URL(simpleurl);
        URLConnection uc = pageURL.openConnection();
        StringBuilder text = new StringBuilder();
        try (Scanner scanner = new Scanner(uc.getInputStream(), "UTF-8")) {
            while (scanner.hasNextLine()) {
                text.append(scanner.nextLine()).append("\n");
            }
        }
        return text.toString();
    } catch (Exception ex) {
        return null;
    }
}

当内容与文件匹配时,方法#equals() 不断返回false。

【问题讨论】:

  • 难道不是因为您吞下了所有换行符并用\n 替换了它们,原因不明,而不是未触及原来可能实际上是\r\n 的换行符吗?会不会是因为您没有检查响应最初使用的编码,并且一直盲目地认为它是 UTF-8?不会是因为您使用了new String() 而没有指定字符集吗?总而言之,您根本不应该担心字符,也不应该将它们按摩成不同的基于字符的格式。只需获取byte[] 的内容并将byte[]byte[] 进行比较。
  • 我刚刚使用\r\n 进行了测试并删除了 UTF-8,但没有成功。我如何将内容获取为 byte[]?
  • @user2527967 对于初学者,我会放弃 Scanner 包装
  • @JanDvorak - 你建议用什么来阅读内容?
  • @user2527967 直接操作inputStream 可能是最好的选择。如果没有,我会检查uc中的其他方法

标签: java file java-io


【解决方案1】:

您不必要地将字节转换为字符并返回,从而丢失原始字节中包含的信息。通常,当您有兴趣读取或操作基于每个字符的字节时,您应该只将字节转换为字符并且您完全了解字符编码的工作原理。这些似乎都不是这里的情况。然后,您应该只是读取和写入原始和未修改的字节,而不是将它们转换为字符。

要将InputStreamURL 读入byte[](而不是String),其中一种方法是:

ByteArrayOutputStream output = new ByteArrayOutputStream();

try (InputStream input = url.openStream()) {
    byte[] buffer = new byte[10240];
    for (int length = 0; (length = input.read(buffer)) > 0;) {
        output.write(buffer, 0, length));
    }
}

byte[] contentFromURL = output.toByteArray();

Apache Commons IOGoogle Guava 对此有 oneliner 方法)

请注意,当您打算将byte[] 保存到文件中时,您只需执行以下操作即可,无需通过new String() 左右将它们按摩成字符:

Files.write(path, contentFromURL);

另请注意,如果您打算立即将任何 InputStream 保存到文件中而不需要中间人 byte[],那么您首先应该这样做:

try (InputStream input = url.openStream()) {
    Files.copy(input, path);
}

无论哪种方式,您最终都会得到一个包含与最初获得的完全相同字节的文件。根据您的代码,您已经知道可以从其中获取byte[],如下所示:

byte[] contentFromFile = Files.readAllBytes(path);

如果您的内容为byte[],并且想将其与另一个byte[] 进行比较,那么您应该只使用Arrays#equals() 而无需将它们按摩到Strings:

Arrays.equals(contentFromURL, contentFromFile);

就是这样。无需使用您甚至尚未确认 HTTP 响应确实以 that 编码编码的字符编码来显式读取它,也无需吞下所有换行符和用一个固定的替换它们,你甚至还没有确认 HTTP 响应确实使用 that 作为换行符。

【讨论】:

    【解决方案2】:

    如果内容真的匹配“test.txt”也应该是UTF-8,你应该阅读它

    new String(Files.readAllBytes(Paths.get(filePath)), "UTF-8")
    

    在 Linux 系统上可以不使用它,但在 Windows 上则不行。但无论哪种情况,您都应该指定预期的编码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多