0

I use InputStreamReader to transfer compressed images. InflaterInputStream is used for decompression of images

InputStreamReader infis =
   new InputStreamReader(
      new InflaterInputStream( download.getInputStream()), "UTF8" );
do {
   buffer.append(" ");
   buffer.append(infis.read());
} while((byte)buffer.charAt(buffer.length()-1) != -1);

But all non-Latin characters become "?" and the image is broken http://s019.radikal.ru/i602/1205/7c/9df90800fba5.gif

With the transfer of uncompressed images I use BufferedReader and everything is working fine

BufferedReader is =
   new BufferedReader(
      new InputStreamReader( download.getInputStream()));
Aubin
  • 14,617
  • 9
  • 61
  • 84
Dmitriy
  • 161
  • 2
  • 12

1 Answers1

5

Reader/Writer classes are designed to work with textual(character based) input/output.

Compressed images are binary, and you need to use either InputStream/OutputStream or nio classes for transferring binary data.

An example using InputStream/OutputStream is given below. This example stores the received data in a local file:

    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {

        bis = new BufferedInputStream(download.getInputStream());
        bos = new BufferedOutputStream(new FileOutputStream("c:\\mylocalfile.gif"));

        int i;
        // read byte by byte until end of stream
        while ((i = bis.read()) != -1) {
            bos.write(i);
        }
    } finally {
        if (bis != null)
            try {
                bis.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        if (bos != null)
            try {
                bos.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
    }
Hakan Serce
  • 11,198
  • 3
  • 29
  • 48
  • The transfer of uncompressed binary images is working properly – Dmitriy May 24 '12 at 18:44
  • gif - http://s019.radikal.ru/i602/1205/7c/9df90800fba5.gif All broken characters - 65533 – Dmitriy May 24 '12 at 18:50
  • gif is a compressed image format. What is the **uncompressed** image format you are using? – Hakan Serce May 24 '12 at 18:52
  • Gif image is compressed zlib, and I get it to a socket in a compressed form. I use it for illustrative purposes only, can be transferred any file formats – Dmitriy May 24 '12 at 18:55
  • @Dimitry please don't get me wrong, but in the first comment (and in your question) you mention that Reader/Writers work for uncompressed binary images. So can you share what this uncompressed image format is. Could it be an ASCII format by any chance? For instance PPM, PGM, PBM, PNM formats can be in ASCII fomat. If that's the case, then we would have a good explanation. That's my point. – Hakan Serce May 24 '12 at 19:00
  • compressed images - means that the image in GIF format, compressed ZLIB library. uncompressed images - means that the image in GIF format, NOT compressed ZLIB library. What is unclear? – Dmitriy May 24 '12 at 19:11
  • "use either InputStream/OutputStream" and I use that (download.getInputStream()) http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html#getInputStream() – Dmitriy May 24 '12 at 19:16
  • So you mean Uncompressed GIF format. The encoding of this format may be somehow "compatible" with UTF8 (at least not producing illegal byte values), I don't know. – Hakan Serce May 24 '12 at 19:20
  • 1
    Can you just try using BufferedInputStream, for instance, instead of BufferedReader, and avoid using Reader/Writers. That will definitely fix your issue. – Hakan Serce May 24 '12 at 19:22
  • What do you want to do with transferred image, store or display or something else? I can post a complete working code if you like. – Hakan Serce May 24 '12 at 19:38
  • The image will be stored. Maybe I'm wrong, but how do I properly write data to a StringBuilder? BufferedInputStream infis = new BufferedInputStream(new InflaterInputStream(download.getInputStream())); buffer.append(infis.read()); - It does not work (infis.read() return int) (char)(int)infis.read() - is also not correct. If no trouble, I will be grateful for the example – Dmitriy May 24 '12 at 19:42
  • 1
    Your stream gives you binary data, and StringBuilder is a character oriented class. Why would you want to put binary data to StringBuilder? If for the sake of debugging/visualization you can convert each byte to hex string as explained here: http://www.coderanch.com/t/526487/java/java/Java-Byte-Hex-String – Hakan Serce May 24 '12 at 19:49
  • I can post some working code as promised, but can you tell me what the example code should do with the received image data? Is it OK if I just store the data in a local file? – Hakan Serce May 24 '12 at 19:52
  • file will be unpacked? (The stream with the image is packed with a zlib library). I use InflaterInputStream because I know exactly what size will be the output file. (i = bis.read()) != -1 - do not fit because after a file transfer connection is not interrupted. I do not know exactly how big the file in compressed form, and I do not know how many bytes I need to take in a condensed form. – Dmitriy May 24 '12 at 20:13
  • No, the example code I posted stores the received data directly. – Hakan Serce May 24 '12 at 20:16
  • problems with obtaining the uncompressed data I do not have – Dmitriy May 24 '12 at 20:31
  • @Dmitriy - maybe it hasn't been said explicitly enough, or has been lost in all the comments: _there should be no Readers/Writers/Strings/StringBuilders/char[]s anywhere in this code_ (regardless of compressed/uncompressed status). is should be InputStreams/OutputStreams/byte[]s all the way from network to disk. – jtahlborn Nov 12 '12 at 20:20
  • @HakanSerce - btw, typically it's much faster to copy streams using a temporary byte[], not byte by byte. – jtahlborn Nov 12 '12 at 20:29