java.io.IOException:流已关闭。将流数据写入多个文件的最佳方式是什么?
我的java代码像twitter一样接收流数据。我需要存储数据,例如每个文件10000条记录。因此,我需要重新创建java.io.IOException:流已关闭。将流数据写入多个文件的最佳方式是什么?,java,stream,filewriter,Java,Stream,Filewriter,我的java代码像twitter一样接收流数据。我需要存储数据,例如每个文件10000条记录。因此,我需要重新创建文件写入程序和缓冲写入程序,以创建一个新文件,然后在其上写入数据 // global variables String stat; long counter = 0; boolean first = true; Date date; SimpleDateFormat format; String currentTime;
文件写入程序
和缓冲写入程序
,以创建一个新文件,然后在其上写入数据
// global variables
String stat;
long counter = 0;
boolean first = true;
Date date;
SimpleDateFormat format;
String currentTime;
String fileName;
BufferedWriter bw = null;
FileWriter fw = null;
public static void main(String[] args) {
String dirToSave = args[0];
String fileIdentifier = args[1];
createFile(dirToSave, fileIdentifier);
StatusListener listener = new StatusListener() {
@Override
public void onStatus(Status status) {
stat = TwitterObjectFactory.getRawJSON(status);
try {
if(bw!=null){
bw.write(stat + "\n");
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
counter++;
if (counter == 10000) {
createFile(dirToSave, fileIdentifier);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
counter = 0;
}
}
};
TwitterStream twitterStream = new TwitterStreamFactory(confBuild.build()).getInstance();
twitterStream.addListener(listener);
// twitterStream.filter(filQuery);
}
public static void createFile(String path, String fileIdentifier) {
date = new Date();
format = new SimpleDateFormat("yyyyMMddHHmm");
currentTime = format.format(date);
fileName = path + "/" + fileIdentifier + currentTime + ".json";
// if there was buffer before, flush & close it first before creating new file
if (!first) {
try {
bw.flush();
bw.close();
fw.close();
} catch (IOException ex) {
Logger.getLogger(LocalFile_All_en.class
.getName()).log(Level.SEVERE, null, ex);
}
} else {
first = false;
}
// create a new file
try {
fw = new FileWriter(fileName);
bw = new BufferedWriter(fw);
} catch (IOException ex) {
Logger.getLogger(Stack.class
.getName()).log(Level.SEVERE, null, ex);
}
}
然而,我总是在几个小时后出错
SEVERE: null
java.io.IOException: Stream closed
编辑:错误消息说,这些代码抛出错误
if (counter == 10000) {
createFile(dirToSave, fileIdentifier);
...
及
我的代码有什么问题?或者有更好的方法来写这样的流数据吗?如果这个错误时不时出现,并且在这个错误之后再写是可以的,我认为当
onStatus()
尝试写刷新它时,bw
可能会被关闭而尚未重新打开
因此,bw
可以不为null,而是关闭。您需要以某种方式同步关闭/打开
例如,将onStatus()
中的这些内容设置为like,这样您就不会直接写入bw
,而是使用一些回调来处理关闭/重新打开新文件
更新:假设这个twitterStream
可以调用onStatus()
,而无需等待上一次调用完成。第一个调用刚刚关闭了流,第二个调用就在写入之后。罕见,但会在很长一段时间内发生
更新2:这也适用于flush()
部件
我已经添加了这个作为一个简短的评论,但是人们经常告诉我们要摆脱静态,尤其是java论证中的全局静态,因为它会在以后导致难以解决/调试的大问题。这可能是一个很好的例子
另请阅读:
后者有一个如何同步并发请求的示例。它是一个多线程程序吗?@Alex否,它只有一个线程。接收流数据并存储到文件。如何调用方法
onStatus
?哪一行引发异常?1)不要调用bw.flush()
,因为这将由bw.close()
完成2) 停止编写可怕的错误处理代码。捕捉异常、记录错误并继续执行,就好像没有发生什么不好的事情一样,这真的很糟糕!不要这样做。若新的FileWriter(文件名)抛出异常,您认为bw
的价值是什么?哎呀!!即使您的程序不是多线程的,底层的TwitterStream
也是如此。它将在线程中调用您的onStatus
方法。因此,你需要考虑一下。
bw.flush();