How to convert an InputStream to a DataHandler?

pcorey picture pcorey · May 13, 2010 · Viewed 75.6k times · Source

I'm working on a java web application in which files will be stored in a database. Originally we retrieved files already in the DB by simply calling getBytes on our result set:

byte[] bytes = resultSet.getBytes(1);
...

This byte array was then converted into a DataHandler using the obvious constructor:

dataHandler=new DataHandler(bytes,"application/octet-stream");

This worked great until we started trying to store and retrieve larger files. Dumping the entire file contents into a byte array and then building a DataHandler out of that simply requires too much memory.

My immediate idea is to retrieve a stream of the data in the database with getBinaryStream and somehow convert that InputStream into a DataHandler in a memory-efficient way. Unfortunately it doesn't seem like there's a direct way to convert an InputStream into a DataHandler. Another idea I've been playing with is reading chunks of data from the InputStream and writing them to the OutputStream of the DataHandler. But... I can't find a way to create an "empty" DataHandler that returns a non-null OutputStream when I call getOutputStream...

Has anyone done this? I'd appreciate any help you can give me or leads in the right direction.

Answer

bugs_ picture bugs_ · May 28, 2012

An implementation of answer from "Kathy Van Stone":

At first create helper class, which create DataSource from InputStream:

public class InputStreamDataSource implements DataSource {
    private InputStream inputStream;

    public InputStreamDataSource(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return inputStream;
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        throw new UnsupportedOperationException("Not implemented");
    }

    @Override
    public String getContentType() {
        return "*/*";
    }

    @Override
    public String getName() {
        return "InputStreamDataSource";
    }
}

And then you can create DataHandler from InputStream:

DataHandler dataHandler = new DataHandler(new InputStreamDataSource(inputStream))

imports:

import javax.activation.DataSource;
import java.io.OutputStream;
import java.io.InputStream;