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

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;

我的java代码像twitter一样接收流数据。我需要存储数据,例如每个文件10000条记录。因此,我需要重新创建
文件写入程序
缓冲写入程序
,以创建一个新文件,然后在其上写入数据

    // 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();