3

所以,使用类似的东西:

for (int i = 0; i < files.length; i++) {
            if (!files[i].isDirectory() && files[i].canRead()) {
                try {
                    Scanner scan = new Scanner(files[i]);
                System.out.println("Generating Categories for " + files[i].toPath());
                while (scan.hasNextLine()) {
                    count++;
                    String line = scan.nextLine();
                    System.out.println("  ->" + line);
                    line = line.split("\t", 2)[1];
                    System.out.println("!- " + line);
                    JsonParser parser = new JsonParser();
                    JsonObject object = parser.parse(line).getAsJsonObject();
                    Set<Entry<String, JsonElement>> entrySet = object.entrySet();
                    exploreSet(entrySet);
                }
                scan.close();
                // System.out.println(keyset);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

        }
    }

当一个人遍历 Hadoop 输出文件时,中间的一个 JSON 对象正在破坏......因为 scan.nextLine() 在将其拆分之前没有获取整行。即,输出是:

  ->0   {"Flags":"0","transactions":{"totalTransactionAmount":"0","totalQuantitySold":"0"},"listingStatus":"NULL","conditionRollupId":"0","photoDisplayType":"0","title":"NULL","quantityAvailable":"0","viewItemCount":"0","visitCount":"0","itemCountryId":"0","itemAspects":{   ...  "sellerSiteId":"0","siteId":"0","pictureUrl":"http://somewhere.com/45/x/AlphaNumeric/$(KGrHqR,!rgF!6n5wJSTBQO-G4k(Ww~~
!- {"Flags":"0","transactions":{"totalTransactionAmount":"0","totalQuantitySold":"0"},"listingStatus":"NULL","conditionRollupId":"0","photoDisplayType":"0","title":"NULL","quantityAvailable":"0","viewItemCount":"0","visitCount":"0","itemCountryId":"0","itemAspects":{   ...  "sellerSiteId":"0","siteId":"0","pictureUrl":"http://somewhere.com/45/x/AlphaNumeric/$(KGrHqR,!rgF!6n5wJSTBQO-G4k(Ww~~

上述大部分数据已被清理(但不是 URL(大多数情况下)......)

并且 URL 继续为: $(KGrHqZHJCgFBsO4dC3MBQdC2)Y4Tg~~60_1.JPG?set_id=8800005007 在文件中......

所以它有点恼火。

这也是条目#112,我已经解析了其他文件而没有错误......但这让我很困惑,主要是因为我没有看到 scan.nextLine() 是如何工作的......

通过调试输出,JSON 错误是由字符串未正确拆分引起的。

几乎忘记了,如果我尝试将有问题的行放在它自己的文件中并解析它,它也可以正常工作。

编辑:如果我在大约同一个地方删除违规行,也会爆炸。

尝试使用 JVM 1.6 和 1.7


解决方法: BufferedReader scan = new BufferedReader(new FileReader(files[i])); 而不是扫描仪......

4

1 回答 1

2

根据您的代码,我能想到的最好解释是,"~~"根据Scanner.nextLine().

行尾的标准是:

  • 与此正则表达式匹配的内容:"\r\n|[\n\r\u2028\u2029\u0085]"
  • 输入流结束

你说文件在 之后继续"~~",所以让我们把 EOF 放在一边,看看正则表达式。这将匹配以下任何一项:

常用的行分隔符:

  • <CR>
  • <NL>
  • <CR><NL>

...以及 Scanner 也可以识别的三种不同寻常的行分隔符形式。

  • 0x0085 是<NEL>“ISO C1 控制”组中的或“下一行”控制代码
  • 0x2028 是 Unicode“行分隔符”字符
  • 0x2029 是 Unicode“段落分隔符”字符

我的理论是您的输入文件中有一种“不寻常”的形式,而这并没有出现在 .... 无论您用来检查文件的工具是什么。


我建议您使用可以显示文件实际字节数的工具检查输入文件;例如odLinux / Unix 系统上的实用程序。另外,请检查这不是由某种字符编码不匹配引起的……或者尝试将二进制数据作为文本读取或写入。

如果这些都没有帮助,那么下一步应该是使用 IDE 的 Java 调试器运行您的应用程序,并单步执行Scanner.hasNextLine()nextLine()调用以找出代码实际在做什么。


几乎忘记了,如果我尝试将有问题的行放在它自己的文件中并解析它,它也可以正常工作。

那很有意思。但是,如果您用于提取线的工具与未显示(假设的)异常线分隔符的工具相同,则此证据不可靠。提取过程可能正在改变导致问题的“材料”。

于 2013-08-10T02:43:40.553 回答