我的java代码接收像twitter这样的流数据。我需要存储数据,例如每个文件10000条记录。所以,我需要重新创建file writer
和buffered writer
来创建一个新文件,然后在其上写入数据。
// 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);
...
和
bw.flush();
我的代码有什么问题?或者有更好的方法来编写像这样的流数据吗?
答案 0 :(得分:1)
如果此错误偶尔出现并且在此错误之后再次写入,我认为可能会发生bw
关闭且在onStatus()
尝试写入flush时仍未重新打开的情况。< / p>
所以bw
可以不是null但是关闭。你需要以某种方式同步结束/开放。
例如,在onStatus()
中创建这样的内容,这样您就不会直接写入bw
,而是使用一些回调来处理关闭/重新打开的新文件。
更新:假设此twitterStream
可以在不等待之前的通话结束的情况下调用onStatus()
。第一个调用刚刚关闭了流,第二个调用就在写入之后。很少见,但会在很长一段时间内发生。
Update2:这也适用于flush()
部分。
我之所以添加这个也是一个简短的评论,但人们经常告诉我们摆脱静态,特别是在java争论中的全局静态,它将导致以后难以解决/调试的大问题。这可能是个好例子。
另请阅读:
Why are static variables considered evil?
Latter有一个如何同步并发请求的示例。