Java 如何提高读取InputStream的性能?

Java 如何提高读取InputStream的性能?,java,sockets,merge,bytearray,bytebuffer,Java,Sockets,Merge,Bytearray,Bytebuffer,这很可能只是一个亲吻的时刻,但我觉得无论如何我都应该问一下 我有一个线程,它从套接字输入流读取。由于我处理的是特别小的数据大小(如我可以预期从中接收的数据大小为100-200字节),因此我将缓冲区数组大小设置为256。作为read函数的一部分,我有一个检查来确保当我从InputStream读取时,我得到了所有的数据。如果没有,那么我将再次递归调用read函数。对于每个递归调用,我将两个缓冲区数组合并在一起 我的问题是,虽然我从未预期使用超过256的缓冲区,但我希望安全。但是,如果绵羊开始飞行,缓

这很可能只是一个亲吻的时刻,但我觉得无论如何我都应该问一下

我有一个线程,它从套接字输入流读取。由于我处理的是特别小的数据大小(如我可以预期从中接收的数据大小为100-200字节),因此我将缓冲区数组大小设置为256。作为read函数的一部分,我有一个检查来确保当我从InputStream读取时,我得到了所有的数据。如果没有,那么我将再次递归调用read函数。对于每个递归调用,我将两个缓冲区数组合并在一起

我的问题是,虽然我从未预期使用超过256的缓冲区,但我希望安全。但是,如果绵羊开始飞行,缓冲区显著增加,读取函数(通过估计)将开始需要更多的时间完成指数曲线

如何提高读取功能和/或缓冲区合并的效率

这是目前的read函数

int BUFFER_AMOUNT = 256;

private int read(byte[] buffer) throws IOException {
   int bytes = mInStream.read(buffer); // Read the input stream

   if (bytes == -1) { // If bytes == -1 then we didn't get all of the data

        byte[] newBuffer = new byte[BUFFER_AMOUNT]; // Try to get the rest
        int newBytes;
        newBytes = read(newBuffer); // Recurse until we have all the data

        byte[] oldBuffer = new byte[bytes + newBytes]; // make the final array size

        // Merge buffer into the begining of old buffer.
        // We do this so that once the method finishes, we can just add the 
        // modified buffer to a queue later in the class for processing.
        for (int i = 0; i < bytes; i++) 
            oldBuffer[i] = buffer[i];

        for (int i = bytes; i < bytes + newBytes; i++) // Merge newBuffer into the latter half of old Buffer
            oldBuffer[i] = newBuffer[i];
        // Used for the recursion

        buffer = oldBuffer; // And now we set buffer to the new buffer full of all the data.
        return bytes + newBytes;
    }
    return bytes;
}
int BUFFER\u AMOUNT=256;
私有int读取(字节[]缓冲区)引发IOException{
int bytes=mInStream.read(buffer);//读取输入流
如果(bytes==-1){//如果bytes==-1,那么我们没有得到所有的数据
byte[]newBuffer=new byte[BUFFER_AMOUNT];//尝试获取其余的
int新细胞;
newBytes=read(newBuffer);//在获得所有数据之前递归
byte[]oldBuffer=newbyte[bytes+newBytes];//设置最终数组大小
//将缓冲区合并到旧缓冲区的开头。
//我们这样做是为了,一旦方法完成,我们就可以添加
//将缓冲区修改为类中稍后的队列以进行处理。
for(int i=0;i
编辑:我是不是有点偏执(不合理),应该将缓冲区设置为2048并调用它

int BUFFER_AMOUNT = 256;
如果不希望在运行时更改,则应为final

if (bytes == -1) {
应该是=


另外,我也不完全清楚您试图用这段代码实现什么。你介意解释一下吗?

我不知道你所说的“小数据量”是什么意思。您应该测量是在内核模式下(然后您直接在套接字上发出过多的
read
s)还是在用户模式下(然后您的算法太复杂)花费的时间

在前一种情况下,只需使用带有4096字节缓冲区的
BufferedInputStream
包装输入并从中读取即可

在后一种情况下,只需使用以下代码:

/**
  * Reads as much as possible from the stream.
  * @return The number of bytes read into the buffer, or -1
  *         if nothing has been read because the end of file has been reached.
  */
static int readGreedily(InputStream is, byte[] buf, int start, int len) {
  int nread;
  int ptr = start; // index at which the data is put into the buffer
  int rest = len; // number of bytes that we still want to read

  while ((nread = is.read(buf, ptr, rest)) > 0) {
    ptr += nread;
    rest -= nread;
  }

  int totalRead = len - rest;
  return (nread == -1 && totalRead == 0) ? -1 : totalRead;
}

这段代码完全避免了创建新对象、调用不必要的方法,而且非常简单。

BufferedInputStream
,正如罗兰所指出的,和
DataInputStream.readFully()
,它取代了所有循环代码。

谢谢你的回答。我知道这是怎么回事,但你拿buf干什么?它看起来就像是随着每次迭代的进行而被克服。任何东西都不能以这种方式改变数据。在这种情况下,请阅读函数的文档。这里我没有覆盖任何字节,我只是继续读取缓冲区。谢谢,这就是我需要的。