【问题标题】:transferring file through socket in Java在Java中通过套接字传输文件
【发布时间】:2012-05-13 10:18:01
【问题描述】:

我正在尝试通过java中的套接字传输文件..实际上我已经能够传输..但是发生了一个问题..问题是发送的文件大小缩小了..例如我传输300mb文件,客户端将只收到 299mb....我想知道可能是什么问题..

服务器端

File myFile = new File (basePath+"\\"+input.readUTF());
byte [] mybytearray  = new byte [1024];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
txtArea.append("Sending... \n");
while (true)
{
    int i = bis.read(mybytearray, 0, mybytearray.length);
            if (i == -1) {
        break;
    }
    output.write(mybytearray, 0, i);
    txtArea.append("Sending chunk " + i + "\n");

}
output.flush();

客户端

output.writeUTF("get");
txtArea.append("Starting to recive file... \n");
                long start = System.currentTimeMillis();
                byte [] mybytearray  = new byte [1024];
                txtArea.append("Connecting... \n");
                output.writeUTF(remoteSelection);
                FileOutputStream fos = new FileOutputStream(basePath+"\\"+remoteSelection);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                int bytesRead = input.read(mybytearray, 0, mybytearray.length);
                while(bytesRead != -1) 
                {
                    bos.write(mybytearray, 0, bytesRead);
                    txtArea.append("got chunk" + bytesRead +"\n");
                    bytesRead = input.read(mybytearray, 0, mybytearray.length);
                }
bos.flush();

【问题讨论】:

  • 您需要在写入之前检查 -1,而不是之后。您还以 Javadoc 中特别警告的方式滥用 available() ;您假设文件大小适合 int;等等等等等等。
  • 添加到 EJP 指出的内容,您还在检查 BufferedInputStream 是否可用,我猜它最多只返回底层输入流的缓冲区长度。
  • 那么我如何检查文件的大小?我尝试使用 byte [] mybytearray = new byte [(int)myFile.length()];之前..但它返回一个错误..当我尝试发送一个大文件时它已经超出了堆..比如 600mb ..
  • 除此之外,但这更优雅 while((bytesRead= input.read(mybytearray, 0, mybytearray.length)) != -1)。
  • @dragon66 猜错了。它基本上返回 buffer.remaining 加上 input.available()。

标签: java file sockets


【解决方案1】:

在 Java 中复制流的规范方法如下:

int count;
byte[] buffer = new byte[8192]; // or whatever you like really, not too small
while ((count = in.read(buffer)) > 0)
{
   out.write(buffer, 0, count);
}

适用于任何长度的输入;不会将整个输入加载到内存中;这样做不会增加延迟。

如果您要发送多个文件,您需要先发送长度,通过 DataOutputStream.writeLong();通过反函数在另一端读取它;并在读取端调整循环条件以在读取到那么多字节后终止。并不像看起来那么简单;留给读者作为练习。

【讨论】:

  • 如何查看文件长度?
  • @BobyHartanto Err, File.length()?
猜你喜欢
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 2020-12-02
  • 2012-07-12
相关资源
最近更新 更多