2

我在通过套接字从服务器发送大字符串到 android 客户端时遇到问题。

字符串大约 10MB。

将数据写入套接字的代码是这样的:

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();

从套接字读取数据的代码是这样的:

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());
}

inputStream所以问题出现在我从OutOfMemoryException读取的地方。我尝试使用从流中读取字符串的不同示例。我尝试使用BufferedInputStream, InputStreamReader, IOUtils, StringBuilder, BufferedReader..etc。当字符串很大时,它们都会给我 OutOfMemory 异常。我用大约 100K 的较小数据进行了测试,它运行良好。

我在服务器端遇到的例外是“连接被对等方重置,套接字写入错误。”

4

2 回答 2

2

您可以在客户端中逐字节读取并逐字节写入文件,这样您就不会将整个字符串保存在内存中。

然后当然通过标记或行读取该文件,而不是一次读取整个字符串

于 2013-10-07T11:58:39.280 回答
1

通过将其存储在一个ByteArrayOutputStream(或类似的)中,您将遇到 Android 中 JVM 的最大堆大小。这是不同的大小,具体取决于设备。请参阅:不同手机/设备和操作系统版本上的 Android 堆大小

正如已经建议的那样,您应该考虑使用文件流将接收到的数据写入磁盘。

于 2013-10-07T12:06:55.053 回答