从套接字和inputStream读取缓慢

问题描述 投票:3回答:3

我使用java.net.Socket在我的应用程序中接收消息。接收速度很慢。接收250 kB持续7秒以上。我可以做些什么来加快这一步。 7秒太多了...

InputStream is = null;
byte[] arr = new byte[8192];
try {
    is = client.getInputStream();
} catch (IOException e) {
    e.printStackTrace();
}

int bytesNumber;
StringBuffer sb = new StringBuffer();

try {
    while ((bytesNumber = is.read(arr)) >= 0) {
        if (bytesNumber == 8192) {
            sb.append(arr);
            continue;
        } else {
            for (int i = 0; i < bytesNumber; i++) {
                sb.append(arr[i]);
            }
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}
java performance sockets stream inputstream
3个回答
0
投票

这是因为如果读取的长度小于缓冲区(arr)的长度,则将一个字符追加一个。而是附加整个缓冲区的内容,无需if:

sb.append(arr,0,butesNumber);

0
投票

如修补匠所述,通常最大的限制是客户端和服务器网络。但是您可以大大简化所拥有的。另外,我认为您的8K缓冲区太小。除非您有严重的内存限制,否则请使用1M或更大的内存。

public String readClient(Client client) throws IOException{
    final int bufferSize = 1024 << 9;

    BufferedInputStream in = new BufferedInputStream(client.getInputStream(),bufferSize);
    byte[] bytes = new byte[bufferSize];
    int bytesRead;
    StringBuilder sb = new StringBuilder(bufferSize);
    try {
        while ((bytesRead = in.read(bytes)) != -1) {
            sb.append(new String(bytes, 0, bytesRead));
        }
    }finally {
        in.close();
    }
    return sb.toString();
}

0
投票

性能不佳的情况不太可能归因于您的代码。在同一系统之间使用curl或类似的东西会获得什么样的性能?

更大的问题是您的代码不太可能做您想要的事情。当前,您将字节数组的表示形式附加到字符串,或将字节的十进制表示形式附加到该字符串。如果服务器发送“ Hello,World!”,您将得到一个字符串“ 7210110810811111144328711111410810033”。对于更长的文件,您会看到类似“ [B @ 76c5a2f7””的信息,这是字节数组的打印方式。

假设您正在接收使用UTF-8编码的文本,我会这样写:

CharArrayWriter str = new CharArrayWriter();
try (InputStream is = client.getInputStream()) {
  Reader r = new InputStreamReader(is, StandardCharsets.UTF_8);
  char[] buffer = new char[8192];
  while (true) {
    int n = r.read(buffer);
    if (n < 0)
      break;
    str.write(buffer, 0, n);
  }
}
System.out.println(str);
© www.soinside.com 2019 - 2024. All rights reserved.