8

To send data to a file on my FTP server, I need to create a custom InputStream implementation that reads database data row by row, converts it to CSV and publishes it via its read() methods: from the database, I get a List<Application> object with the data. For each Application object, I want to create a line in the CSV file.

My idea is to load all the data in the constructor and then override the read method. Do I need to override all InputStream's methods? I tried googling for some examples but didn't succeed - could you eventually give me a link to one?

4

6 回答 6

12

You only nead to implement the read() method without parameters. All other methods are implemented as calls to that method. For performance reasons (and even ease of implementation) it might be easier to implement the three-argument read() method instead and re-implement the no-args read() method in terms of that method.

于 2011-01-26T13:44:20.347 回答
9

我在实施我的InputStream.

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

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

    不覆盖此方法将导致任何测试此流是否可读的尝试都返回 false。例如,如果您将您的内容提供inputStream给 a ,当您调用 时inputStreamReader,此阅读器将始终返回 falsereader.ready()

  2. 返回 -1 在read(). 文档没有强调它:

    如果由于到达流的末尾而没有可用的字节,则返回值 -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()等。

于 2015-12-29T08:57:28.773 回答
3

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

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

使用out.getSupplier().getInput()你得到你的 InputStream。

于 2011-01-26T14:30:59.397 回答
1

There's absolutely no need to create a custom InputStream. Use ByteArrayInputStream, something like this:

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

Especially given this quote:

My idea is to load all the data in the constructor and then override the read method.

If you do it like this, you gain absolutely nothing by implementing a custom InputStream. It's pretty much equivalent to the approach I outlined above.

于 2011-01-26T13:47:58.653 回答
1

为什么需要自定义输入流?为什么不直接将生成的 csv 数据写入正在写入 ftp 服务器的输出流中呢?

于 2011-01-26T16:09:05.930 回答
0

If the data is not too large, you could:

  • Read it all
  • Convert to CSV (text)
  • Get the text bytes (via String.getBytes(encoding))
  • But the byte array in a ByteArrayInputStream
于 2011-01-26T13:47:38.717 回答