Scanner nextLine(),仅提取部分

时间:2013-08-10 01:07:07

标签: java java.util.scanner

所以,使用类似的东西:

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继续为:     $(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])); 而不是扫描仪....

1 个答案:

答案 0 :(得分:2)

根据您的代码,我可以提出的最佳解释是,根据"~~"使用的标准,该行确实在Scanner.nextLine()之后结束。

行尾的标准是:

  • 符合此正则表达式的内容:"\r\n|[\n\r\u2028\u2029\u0085]"
  • 输入流的结尾

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

通常的行分隔符:

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

......以及扫描仪也识别的三种不同形式的行分隔符。

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

我的理论是,你的输入文件中有一个“不寻常”的形式,这并没有出现在......用于检查文件的任何工具。


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

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


  

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

这很有趣。但是,如果用于提取线的工具与未显示(假设的)异常线分隔符的工具相同,则此证据不可靠。提取过程可能会改变导致问题的“东西”。