【问题标题】:Java, send and receive a file with socket: is it necessary use bufferedinputstream and bufferedoutputstream?Java,用socket发送和接收文件:有必要使用bufferedinputstream和bufferedoutputstream吗?
【发布时间】:2013-06-09 15:32:00
【问题描述】:

我正在尝试在客户端-服务器应用程序中编写两种使用 java 套接字发送和接收文件的方法,但我有一些疑问:

我使用FileInputStreamFileOutputStreamBufferedInputStreamBufferedOutputStream 更好吗?

static protected long send_file(File file, DataOutputStream output) throws IOException, FileNotFoundException, SecurityException
{
    byte[] buffer = new byte[1024];
    long count = 0;
    int nread = 0;

    FileInputStream file_input = new FileInputStream(file);

    output.writeLong(file.length());

    while((nread = file_input.read(buffer)) != -1) 
    {
        output.writeInt(nread);

        output.write(buffer, 0, nread);
        count += nread;
    }

    output.flush();
    file_input.close();

    return count;   
}


static protected long receive_file(File file, DataInputStream input) throws IOException, FileNotFoundException, SecurityException, EOFException
{
    byte[] buffer = new byte[1024];
    long dim_file = 0;
    long count = 0;
    int nbyte = 0;
    int nread = 0;
    int n = 0;

    FileOutputStream file_output = new FileOutputStream(file);

    dim_file = input.readLong();

    while(count < dim_file) 
    {
        nbyte = input.readInt();

        nread = input.read(buffer, 0, nbyte);
        if(nread == -1)
        {
            file_output.close();
            throw new EOFException();
        }

        while(nread < nbyte) 
        {
            n = input.read(buffer, nread, nbyte-nread);

            if(n == -1)
            {
                file_output.close();
                throw new EOFException();
            }

            nread += n;
        }

        file_output.write(buffer, 0, nread);

        count += nread;
    }

    file_output.flush();
    file_output.close();

    return count;   
}

我不明白BufferedInputStreamBufferedOutputStream的必要性:

在第一种方法中,我使用一个 1024 字节的缓冲区,首先我用FileInputStream.read(byte[] b) 填充它,然后用DataOutputStream.write(byte[] b, int off, int len) 将它发送到套接字。

在第二种方法同上:首先我用DataInputStream.read(byte[] b) 填充缓冲区,然后用FileOutputStream.write(byte[] b, int off, int len) 写入文件。

那么为什么要使用BufferedInputStreamBufferedOutputStream? 这样,如果我了解它们的工作原理,我会先在缓冲区中写入字节,然后 BufferedInputStreamBufferedOutputStream 在它们的缓冲区中复制字节。

【问题讨论】:

  • 必要的,没有。可取的,是的。

标签: java sockets bufferedinputstream bufferedoutputstream


【解决方案1】:

如果您不使用缓冲流,Java IO 将在您每次写入/读取一个字节时进行操作系统调用,无论是写入/读取文件还是套接字,效率极低。

【讨论】:

  • 每次调用一个读或写方法。不是一回事。
  • 为什么? FileInputStream.read() - 本机,FileOutputStream.write(byte) - 本机
  • 但我使用自己的缓冲区与 FileInputStream.read(byte[] b) 和 DataInputStream.read(byte[] b)。
  • 如果你使用读/写字节数组(如你的例子)你不需要缓冲流。
  • 确实有原生方法,但不只是单字节。
【解决方案2】:

这不是更好。他们提供不同的东西。当 fileoutputstream 写入文件时,BuffereOutputStreams 写入缓冲区(因此得名:))。 您应该将它们结合起来,以获得最佳性能。例如

BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("output.txt"))

然后,您的程序将首先将所有内容写入缓冲区,并仅在刷新缓冲区时将其转储到文件中

【讨论】:

  • 所以我将拥有: ...socket DataInputStream--->buffer[1024]--->BufferedOutputStream--->buffer[?]---->FileOutputStream---->文件。但是我应该为 BufferedOutputStream 使用什么缓冲区大小?默认?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多