CSV导出器的InputStream

时间:2014-06-13 14:22:29

标签: java io

我有以下方法:

public String exportAsCsv(CqlQuery query) {
    Iterator<String> result = queryService.execute(.....);
    StringBuilder buf = new StringBuilder();
    for (String nextLine : result) {
       buf.append(nextLine);
    }
    return buf.toString();
}

它执行一些返回Iterator<String>的查询 - 它包含千兆字节的数据,因此将其附加到StringBuilder并不是最好的想法......

我想更改我的方法,以便它返回InputStream

这可能是一种可能的实现(伪代码):

public InputStream exportAsCsv(CqlQuery query) {
    final Iterator<String> result = queryService.execute(query,false);
    return new MagicalInputStream(){
            @Overwrite
            byte[] readNext() {
                if(!result.hasNext()) { 
                   return null; 
                 } else { 
                   return result.next().getBytes();
                 }
            }       
    }
}

我正在寻找InputStream,我必须实现抽象方法(如byte[] readNext()),它将用于逐个读取数据块。因此,此输入流必须缓冲读取块,将其流回,并且当其缓冲区为空时,它应读取下一个块。 我的想法是,当“客户端”从输入流中拉出下一个字节时,我只读取Iterator中的下一个元素。

或者可能有另一种可能性来更改我的方法,以便它返回InputStream而不是String - 任何想法?

1 个答案:

答案 0 :(得分:2)

如果您允许方法接受InputStream,则可以避免整个java.io.Writer实施。您可以将它们附加到提供的Writer,而不是将字符串附加到内存中StringBuilder

public void exportAsCsv(CqlQuery query, Writer writer) {
    Iterator<String> result = queryService.execute(.....);
    for (String nextLine : result) {
        writer.append(nextLine);
    }
}   

如果你真的想要一个InputStream,你可以尝试这样的事情:

public InputStream exportAsCsv(CqlQuery query) {
    Iterator<String> result = queryService.execute(.....);
    return new SequenceInputStream(asStreamEnum(result));
}   

private Enumeration<InputStream> asStreamEnum(final Iterator<String> it) {
    return new Enumeration<InputStream>() {

        @Override
        public boolean hasMoreElements() {
            return it.hasNext();
        }

        @Override
        public InputStream nextElement() {
            try {
                return new ByteArrayInputStream(it.next().getBytes("UTF-8"));
            } catch (UnsupportedEncodingException ex) {
                throw new RuntimeException(ex);
            }
        }

    };
}

我还没有真正测试过这种方法,所以请注意;但从概念上讲,我认为这就是你所追求的目标。