java.io.IOException:Stream已关闭。将流数据写入多个文件的最佳方法是什么?

时间:2017-10-19 07:22:22

标签: java stream filewriter

我的java代码接收像twitter这样的流数据。我需要存储数据,例如每个文件10000条记录。所以,我需要重新创建file writerbuffered 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();

我的代码有什么问题?或者有更好的方法来编写像这样的流数据吗?

1 个答案:

答案 0 :(得分:1)

如果此错误偶尔出现并且在此错误之后再次写入,我认为可能会发生bw关闭且在onStatus()尝试写入flush时仍未重新打开的情况。< / p>

所以bw可以不是null但是关闭。你需要以某种方式同步结束/开放。

例如,在onStatus()中创建这样的内容,这样您就不会直接写入bw,而是使用一些回调来处理关闭/重新打开的新文件。

更新:假设此twitterStream可以在不等待之前的通话结束的情况下调用onStatus()。第一个调用刚刚关闭了流,第二个调用就在写入之后。很少见,但会在很长一段时间内发生。

Update2:这也适用于flush()部分。

我之所以添加这个也是一个简短的评论,但人们经常告诉我们摆脱静态,特别是在java争论中的全局静态,它将导致以后难以解决/调试的大问题。这可能是个好例子。

另请阅读:

Why are static variables considered evil?

Volatile Vs Static in java

Latter有一个如何同步并发请求的示例。