2

I have a problem with sending large string through socket from server to android client.

String is about 10MB.

Code for writing data to socket is this:

int socketTimeout = 200;
socket = new Socket(client.getHost(), client.getPort());
socket.setSoTimeout(socketTimeout);
OutputStreamWriter oos=new OutputStreamWriter(socket.getOutputStream());
String d = data.getData().toString() + "\n";
oos.write(d);

oos.flush();

Code for reading data from socket is this:

Socket s = params[0];
InputStream is = null;
try {
    is = s.getInputStream();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    int nRead;
    byte[] data = new byte[32768];

    while ((nRead = is.read(data, 0, data.length)) != -1) {
        baos.write(data, 0, nRead);
    }
    return new String(baos.toByteArray());
}

So problem comes at line where I'm reading from inputStream where I get OutOfMemoryException. I tried using different examples of reading string from stream. I tried with BufferedInputStream, InputStreamReader, IOUtils, StringBuilder, BufferedReader ..etc. and all of them give me OutOfMemory exception when the string is large. I tested with smaller data something around 100K and it works perfectly.

Exception that I get on server-side is "Connection is reset by peer, socket write error."

Prabhakaran Ramaswamy
  • 25,706
  • 10
  • 57
  • 64
drago
  • 1,207
  • 4
  • 24
  • 45
  • 2
    The issue is there is not enough memory to store **all the content**. `ByteArrayOutputStream` **holds all the content in the RAM** before doing anything with it. Write it directly to a file in small chunks (128kB, or such), by using a FileOutputStream for example – ppeterka Oct 07 '13 at 12:00
  • @user2511414 32kB **huge**? On an Arduino, yes, but on any meaningful Android phone, I don't think so... – ppeterka Oct 07 '13 at 12:01
  • yes of course it's looks huge for me. and maybe this is because the heap is going to huge and huge! maybe you need to write the data directly into some file! –  Oct 07 '13 at 12:04

2 Answers2

2

You can read byte by byte in the client and write to a File byte by byte, in that way you are not holding the whole string in memory.

And then of course read that file by tokens or lines, not the whole string at once

David Hofmann
  • 5,683
  • 12
  • 50
  • 78
1

By storing it in a ByteArrayOutputStream (or similar), you are coming up against the maximum heap size for the JVM in Android. This is a different size depending on the device. See: Android heap size on different phones/devices and OS versions

As has already been suggested, you should consider using a file stream to write the received data to disk.

Community
  • 1
  • 1
Steve
  • 7,171
  • 2
  • 30
  • 52