Can';t读取以前用Java编写的JSON数据(未终止的字符串错误)
我正在使用twitter4j软件包进行信息检索课程,并收集了一些tweet。然而,在作业的下一部分,我将使用Lucene对tweets进行索引。为了做到这一点,我的想法是将tweet作为JSON字符串保存到一个文件中,然后在需要时重新读取它们。然而,我遇到了一个错误 在编写文件时,我可以很好地看到整个JSON对象。整个对象相当大(2500个字符)。但是,当从文件读回时,我在xxxx处得到一个Can';t读取以前用Java编写的JSON数据(未终止的字符串错误),java,json,io,twitter4j,Java,Json,Io,Twitter4j,我正在使用twitter4j软件包进行信息检索课程,并收集了一些tweet。然而,在作业的下一部分,我将使用Lucene对tweets进行索引。为了做到这一点,我的想法是将tweet作为JSON字符串保存到一个文件中,然后在需要时重新读取它们。然而,我遇到了一个错误 在编写文件时,我可以很好地看到整个JSON对象。整个对象相当大(2500个字符)。但是,当从文件读回时,我在xxxx处得到一个未终止的字符串。我使用TwitterObjectFactory方法来写入和读取字符串。下面是一个示例代码:
未终止的字符串。我使用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和其他国际字符时应能工作,无论您是否提供了正确的字符集:-/问题可能是引号字符前的反斜杠。也许还有其他潜在的原因。