InputStream的自定义实现

时间:2011-01-26 13:40:07

标签: java ftp inputstream java-io

要将数据发送到我的FTP服务器上的文件,我需要创建一个自定义的InputStream实现,逐行读取数据库数据,将其转换为CSV并通过其read()方法发布它:从数据库中,我得到带有数据的List<Application>对象。对于每个Application对象,我想在CSV文件中创建一行。

我的想法是在构造函数中加载所有数据,然后覆盖read方法。我是否需要覆盖所有InputStream的方法?我尝试使用谷歌搜索一些例子,但没有成功 - 你最终能给我一个链接吗?

6 个答案:

答案 0 :(得分:9)

你只需要实施the read() method without parameters。所有其他方法都实现为对该方法的调用。出于性能原因(甚至易于实现),可能更容易实现the three-argument read() method instead并根据该方法重新实现no-args read()方法。

答案 1 :(得分:5)

我在实施InputStream时遇到的一些非常重要的问题。

  1. 覆盖可用()。正如Javadoc所说:

      

    类InputStream的可用方法始终返回0。   这个方法应该被子类覆盖。

    不覆盖此方法将导致任何诱惑测试此流是否可读 return false 。例如,如果您将inputStream提供给inputStreamReader,则在您调用reader.ready()时,此阅读器将始终返回false

  2. read()中返回-1。该文件没有强调它:

      

    如果由于到达流末尾而没有可用字节,则返回值-1。此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常。

    如果您选择在没有可用数据时屏蔽read(),则必须在某些情况下记住return -1。不执行此操作可能会导致另一个read(byte b[], int off, int len)阻止源中的以下代码:

    for (; i < len ; i++) {// default len is a relative large number (8192 - readPosition)
        c = read();
        if (c == -1) {
            break;
        }
        b[off + i] = (byte)c;
    }
    

    这导致一些(如果不是全部)高级读取块,如读者的readLine(), read()等。

答案 2 :(得分:3)

对于可能较大的数据,您可以使用guava中的 com.google.common.io.FileBackedOutputStream

Javadoc:一个OutputStream,它开始缓冲到一个字节数组,但是一旦数据达到可配置的大小,就会切换到文件缓冲。

使用out.getSupplier().getInput()即可获得InputStream。

答案 3 :(得分:1)

为什么需要自定义输入流?为什么不在编写csv数据时将其生成到写入ftp服务器的输出流?

答案 4 :(得分:0)

如果数据不是太大,您可以:

  • 全部阅读
  • 转换为CSV(文字)
  • 获取文本字节(通过String.getBytes(encoding)
  • 但是ByteArrayInputStream
  • 中的字节数组

答案 5 :(得分:0)

绝对不需要创建自定义InputStream。使用ByteArrayInputStream,如下所示:

public static InputStream createStream(){
    final String csv = createCsvFromDataBaseValues();
    return new ByteArrayInputStream(csv.getBytes());
}

特别是这个引用:

  

我的想法是加载所有数据   构造函数然后覆盖读取   方法

如果您这样做,那么通过实施自定义InputStream,您绝不会获得任何好处。它几乎等同于我上面概述的方法。