Can';t读取以前用Java编写的JSON数据(未终止的字符串错误)

Can';t读取以前用Java编写的JSON数据(未终止的字符串错误),java,json,io,twitter4j,Java,Json,Io,Twitter4j,我正在使用twitter4j软件包进行信息检索课程,并收集了一些tweet。然而,在作业的下一部分,我将使用Lucene对tweets进行索引。为了做到这一点,我的想法是将tweet作为JSON字符串保存到一个文件中,然后在需要时重新读取它们。然而,我遇到了一个错误 在编写文件时,我可以很好地看到整个JSON对象。整个对象相当大(2500个字符)。但是,当从文件读回时,我在xxxx处得到一个未终止的字符串。我使用TwitterObjectFactory方法来写入和读取字符串。下面是一个示例代码:

我正在使用twitter4j软件包进行信息检索课程,并收集了一些tweet。然而,在作业的下一部分,我将使用Lucene对tweets进行索引。为了做到这一点,我的想法是将tweet作为JSON字符串保存到一个文件中,然后在需要时重新读取它们。然而,我遇到了一个错误

在编写文件时,我可以很好地看到整个JSON对象。整个对象相当大(2500个字符)。但是,当从文件读回时,我在xxxx处得到一个
未终止的字符串。我使用TwitterObjectFactory方法来写入和读取字符串。下面是一个示例代码:

写作:

        public void onStatus(Status status) {
            try{
                String jsonString = TwitterObjectFactory.getRawJSON(status);
                output.write(jsonString+"\n");
                numTweets++;
                if(numTweets > 10){
                    synchronized(lock){
                        lock.notify();
                    }
                }
            }
            catch(IOException e){
                e.printStackTrace();
            }
        }
阅读:

    Scanner input = new Scanner(file);


    while(input.hasNext()){
        Status status = TwitterObjectFactory.createStatus(input.nextLine());
        System.out.println(status.getUser().getScreenName());
    }
这只在某些时候起作用。如果我多次运行该程序并收到许多tweet,那么在从文件中读取2-3条tweet后,该程序几乎总是崩溃,并且总是出现相同的错误。如果你想复制代码,你可以按照。为了在10条tweet后关闭流,我添加了一个synchronized块,但是没有必要复制错误

有人能解释发生了什么事吗?我的猜测是,我将JSON编码到文件中的方式有问题。我正在使用
BufferedWriter
包装
OutputStreamWriter
,以便以UTF-8格式输出

编辑:我确实关闭了流。下面是代码的底部片段:

    twitterStream.addListener(listener);
    twitterStream.sample("en");

    try{
        synchronized(lock){
            lock.wait();
        }
    }
    catch(InterruptedException e){
        e.printStackTrace();
    }

    twitterStream.clearListeners();
    twitterStream.cleanUp();
    twitterStream.shutdown();
    output.close();

我没有看到正确关闭
BufferedWriter
的代码。如果在第一个程序结束前不手动关闭它,那么数据可能会保留在内部缓冲区中,并且永远不会写入文件

您还可以尝试在文本编辑器中打开文件并查看内容。类似或的工具允许您验证/美化内容以查看错误


最后,尝试
BufferedReader(新的InputStreamReader(新文件InputStream(文件),“UTF-8”))
。输入中的非ASCII字符可能会混淆扫描仪

在通知阅读器之前,您可能需要刷新输出。否则,部分字符串将保留在缓冲区中

    public void onStatus(Status status) {
        try{
            String jsonString = TwitterObjectFactory.getRawJSON(status);
            output.write(jsonString+"\n");
            output.flush();
            numTweets++;
            if(numTweets > 10){
                synchronized(lock){
                    lock.notify();
                }
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }

是否确实在读取之前正确关闭了文件流?@PavelHoll是。它们是两个独立的程序,我只是在编写器终止后才阅读。我显示的同步锁块允许我在Writer程序终止之前关闭TwitterStream和BufferedWriter对象。看着你的代码(不熟悉Twitter4j),我在关闭输出流时会感觉到竞争状况(在
onStatus
仍在写第11条tweet时关闭它)。@Pavelhol根据Aaron回答中建议的链接,输出是完全有效的。这是谷歌硬盘中的文件:对不起,我不清楚。使用synchronized块是为了在接收到一定数量的tweet后关闭流。请看上面的编辑。我尝试并检查了所有的推文。这似乎是有效的。我怎么读会有问题吗?当抛出异常时,我打印该行,它确实在一个随机位置被截断,但当我查看文件本身时,该行实际上继续运行。@Teofrostus:关闭看起来不错<代码>扫描仪应该读取整行内容,无论它有多长。您能尝试用
缓冲读取器
替换它吗?另外,不要忘记使用
InputStreamReader
阅读,这样您就可以指定输入编码了。哇,这是出于某种原因而起作用的。使用BufferedReader,突然之间就没有任何问题了。你知道为什么会这样吗?我不确定<代码>扫描仪在输入包含Umlauts和其他国际字符时应能工作,无论您是否提供了正确的字符集:-/问题可能是引号字符前的反斜杠。也许还有其他潜在的原因。