5

我正在尝试使用 Java 将文件从一台计算机发送到另一台计算机。我已经编写了下面的代码,如果发送者和接收者都在同一台计算机上启动,但如果它们在不同的机器上工作,则接收文件大小大于原始文件并且已损坏。

注意:我正在尝试传输最大 10 MB 的文件。

我怎样才能解决这个问题?

发件人:

ServerSocket server_socket = new ServerSocket(8989);
File myFile = new File(myPath);

Socket socket = server_socket.accept();
int count;
byte[] buffer = new byte[1024];

OutputStream out = socket.getOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(myFile));
while ((count = in.read(buffer)) > 0) {
     out.write(buffer, 0, count);
     out.flush();
}
socket.close();

接收者:

Socket socket = new Socket(address, 8989);
FileOutputStream fos = new FileOutputStream(anotherPath);
BufferedOutputStream out = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int count;
InputStream in = socket.getInputStream();
while((count=in.read(buffer)) >0){
    fos.write(buffer);
}
fos.close();
socket.close();
4

3 回答 3

23

在客户端,您最多 count写入字节并发送它们:

while ((count = in.read(buffer)) > 0) {
  out.write(buffer, 0, count);

在服务器端,您最多 count读取字节 - 但随后您将整个缓冲区写入文件!

while((count=in.read(buffer)) > 0){
  fos.write(buffer);

只需将其更改为:

fos.write(buffer, 0, count);

你会安全的。顺便说一句,您的程序还有另一个小错误:read()可以返回0并不意味着InputStream结束。改用>=

count = in.read(buffer)) >= 0

您是否IOUtils.copy(InputStream, OutputStream)从 Apache Commons 考虑过?它会将您的整个while循环减少到:

OutputStream out = socket.getOutputStream();
InputStream in = new FileInputStream(myFile);
IOUtils.copy(in, out);
socket.close();

更少的代码编写,更少的代码测试。缓冲是在内部完成的。

于 2012-11-25T21:31:22.203 回答
3

请记住,in.read(buffer)不一定要用新数据填满整个缓冲区。因此,您应该确保不要写入整个缓冲区。改变

while((count=in.read(buffer)) >0){
    fos.write(buffer);
}

while((count=in.read(buffer)) >0){
    fos.write(buffer, 0, count);
}
于 2012-11-25T21:31:20.487 回答
1

发件人

Socket sock = new Socket("127.0.0.1", 5991);
        System.out.println("Connecting.........");
        File myFile = new File("/root/qrcode/");
        File[] files = myFile.listFiles();
       OutputStream os = sock.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(os);
                            DataOutputStream dos = new DataOutputStream(bos);

                            dos.writeInt(files.length);
                            long totalBytesRead = 0;
                            int percentCompleted = 0;
                            for(File file : files)
                            {
                                     long length = file.length();
                                     dos.writeLong(length);

                                     String name = file.getName();
                                     dos.writeUTF(name);

                                     FileInputStream fis = new FileInputStream(file);
                                     BufferedInputStream bis = new BufferedInputStream(fis);

                                     int theByte = 0;
                                     while((theByte = bis.read()) != -1)
                                     {
                                        totalBytesRead += theByte;


                                        bos.write(theByte);
                                     }
                                    //  System.out.println("file read");
                                     bis.close();
                                 }

                                dos.close();


        //Closing socket  
        sock.close();

接收者

ServerSocket serverSocket = new ServerSocket(5991);  

    while(true) {  
        Socket clientSocket = null; 
        System.out.println("Starting...");
        clientSocket = serverSocket.accept();  

        InputStream in = clientSocket.getInputStream(); //used

        BufferedInputStream bis = new BufferedInputStream(in);

        String dirPath  ;
        dirPath = "/root/NewFolder";

        try{
            DataInputStream dis = new DataInputStream(bis);

            int filesCount = dis.readInt();
            File[] files = new File[filesCount];
            long f_l = 0;
            int count =0 ;
            long totalBytesRead = 0;
            int percentCompleted = 0;

            for(int i = 0; i < filesCount; i++)
            {
                long fileLength = dis.readLong();
                String fileName = dis.readUTF();

                f_l = f_l +fileLength;
                files[i] = new File(dirPath + "/" + fileName);

                FileOutputStream fos = new FileOutputStream(files[i]);
                BufferedOutputStream bos = new BufferedOutputStream(fos);

                int tot = 0;
                for(int j = 0; j < fileLength; j++) {

                    bos.write(bis.read());
                }

                bos.close();

            }

        }catch(Exception ex)
        {
            System.out.println("error in socket programming ");
        }
    }
于 2016-06-01T12:16:58.007 回答