14

How can we read or use the contents of outputstream. In my case, I am using a method having signature.

public static OutputStream decryptAsStream(InputStream inputStream, String encryptionKey)

This method return OutputStream. I want get OutputStream to String. Is it possible to pipe the output from an java.io.OutputStream to a String in Java?

Viraj Dhamal
  • 5,165
  • 10
  • 32
  • 41
Avyaan
  • 1,285
  • 6
  • 20
  • 47
  • You don't read from outputstream - you write to outputstream: http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html#write(byte[]) – Nir Alfasi Aug 03 '13 at 05:29

4 Answers4

13

How can we read or use the contents of outputstream.

In general you can't. An OutputStream is an object that you write bytes to. The general API doesn't provide any way to get the bytes back.

There are specific kinds of output stream that would allow you to get the bytes back. For instance:

  • A ByteArrayOutputStream has a method for getting the byte array contents.
  • A PipeOutputStream has a corresponding PipeInputStream that you can read from.
  • If you use a FileOutputStream to write to file, you can typically open a FileInputStream to read the file contents ... provided you know the file pathname.

Looking at that method, it strikes me that the method signature is wrong for what you are trying to do. If the purpose is to provide an encrypter for a stream, then the method should return an InputStream. If the purpose is to write the encrypted data somewhere, then the method should return void and take an extra parameter that is the OutputStream that the method should write to. (And then the caller can use an OutputStream subclass to capture the encrypted data ... if that is what is desired.)

Another alternative that would "work" is to change the method's signature to make the return type ByteArrayOutputStream (or a file name). But that is not a good solution because it takes away the caller's ability to decide where the encrypted output should be sent.


UPDATE

Regarding your solution

    OutputStream os = AESHelper.decryptAsStream(sourceFile, encryptionKey);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos = (ByteArrayOutputStream) os;  
    byte[] imageBytes = baos.toByteArray();  
    response.setContentType("image/jpeg");  
    response.setContentLength(imageBytes.length);  
    OutputStream outs = response.getOutputStream();  
    outs.write(imageBytes);

That could work, but it is poor code:

  • If AESHelper.decryptAsStream is a method that you wrote (and it looks like it is!), then you should declare it as returning a ByteArrayOutputStream.

  • If it is already declared as returning a ByteArrayOutputStream you should assign it directly to baos.

  • Either way, you should NOT initialize baos to a newly created ByteArrayOutputStream instance that immediately gets thrown away.

It is also worth noting that the Content-Type is incorrect. If you sent that response to a browser, it would attempt to interpret the encrypted data as an image ... and fail. In theory you could set a Content-Encoding header ... but there isn't one that is going to work. So the best solution is to send the Content-Type as "application/octet-stream".

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
11

You can do something like following :

  OutputStream output = new OutputStream()
    {
        private StringBuilder string = new StringBuilder();
        @Override
        public void write(int x) throws IOException {
            this.string.append((char) x );
        }

        public String toString(){
            return this.string.toString();
        }
    };
Ushani
  • 1,199
  • 12
  • 28
2

Mainly you can use outputstreams to send the file contents as @The New Idiot mentioned. .pdf files, zip file, image files etc.

In such scenarios, get the output stream of your servlet and to that write the contentes

OutputStream outStream = response.getOutputStream();
FileInputSteram fis = new FileInputStream(new File("abc.pdf));
byte[] buf = new byte[4096];
int len = -1;
while ((len = fis.read(buf)) != -1) {
    outStream .write(buf, 0, len);
}
response.setContentType("application/octect");(if type is binary) else 
response.setContentType("text/html");
outStream .flush();
outStream.close();
UVM
  • 9,776
  • 6
  • 41
  • 66
0

If you got the OutputStream from the response , you can write the contents of the OutputStream to the response which will be sent back to the browser . Sample code :

OutputStream outStream = response.getOutputStream();
response..setHeader("Content-Disposition", "attachment; filename=datafile.xls");
response.setContentType("application/vnd.ms-excel");
byte[] buf = new byte[4096];
int len = -1;
while ((len = inStream.read(buf)) != -1) {
    outStream.write(buf, 0, len);
}

outStream.flush();
outStream.close();

Read this : Content-Disposition:What are the differences between “inline” and “attachment”?


In your case the method definition is :

public static OutputStream decryptAsStream(InputStream inputStream,
                                            String encryptionKey)

So you can get the OutputStream from that method as :

OutputStream os = ClassName.decryptAsStream(inputStream,encryptionKey);

And then use the os .

Community
  • 1
  • 1
AllTooSir
  • 48,828
  • 16
  • 130
  • 164