>  기사  >  Java  >  파일의 중단점 재개 업로드를 구현하는 Java 소켓에 대한 자세한 소개(코드 예)

파일의 중단점 재개 업로드를 구현하는 Java 소켓에 대한 자세한 소개(코드 예)

不言
不言앞으로
2019-03-13 11:59:403636검색

이 기사는 Java 소켓 구현의 파일 재개(코드 예제)에 대한 자세한 소개입니다. 필요한 친구가 참고할 수 있기를 바랍니다.

얼마전부터 자바 쓰레기인 저에게 작업이 필요했기 때문에 자바를 사용하여 간단한 파일 중단점 이력서 전송을 구현하는 방법을 공부하기 시작했습니다. 소위 파일 재개에 대해 제가 이해한 바는 어떤 이유로 파일을 전송하면 프로그램 실행이 중지되고 파일이 종료되어 다음에 파일을 다시 전송할 때 마지막 전송부터 파일이 전송될 수 있다는 것입니다. 다시 전송할 필요 없이 처음부터 시작합니다.

파일 전송 과정은 보내는 사람과 받는 사람으로 나누어집니다. 결국 내 생각은 이렇습니다.

1: 전송이 시작되기 전에 보낸 사람은 먼저 받는 사람에게 확인 메시지를 보낸 다음 파일을 보냅니다. 파일 이름
2: 수신자는 확인 메시지를 받은 후 보낸 사람이 보낸 파일 이름을 수신한 후 보낸 사람에게 파일 이름이 지정되었음을 알리는 확인 메시지를 보냅니다. 그러면 수신자는 수신된 파일 이름을 기반으로 ".temp" 파일 개체와 ".temp" RandomAccessFile 개체를 기반으로 파일을 생성합니다. 이 File 객체에 해당하는 파일의 길이(크기)를 가져오고(이 길이는 수신자가 수락한 길이입니다. 이전에 파일을 수신하지 않은 경우 길이는 0입니다) 파일 길이를 발신자에게 보냅니다.
3: 보낸 사람은 확인 메시지를 받은 후 받는 사람이 보낸 파일의 길이를 받은 다음 보낼 파일의 전체 길이를 받는 사람에게 보내고 확인 메시지를 받는 사람에게 보냅니다. 그러면 수신자가 보낸 파일의 길이에 따라 파일의 길이에 해당하는 위치부터 전송이 시작됩니다.
4: 수신자는 확인 메시지를 받은 후 발신자가 보낸 데이터를 수락한 다음 파일 끝부터 씁니다. 승인이 완료되면 ".temp" 파일을 일반 파일명으로 변경합니다.

다음과 같이 프로세스를 그립니다.

파일의 중단점 재개 업로드를 구현하는 Java 소켓에 대한 자세한 소개(코드 예)

중단점 재개를 달성하는 핵심은 RandomAccessFile을 사용하는 것입니다. 이 유형의 인스턴스는 임의 액세스 파일 읽기 및 쓰기를 지원합니다.

진행률 표시줄 및 파일 선택기와 같은 일부 GUI를 추가합니다. 최종 주요 코드는 다음과 같습니다.

Sender code:

import
 java.awt.Color;
import
 java.awt.Container;
import
 java.awt.Dimension;
import
 java.awt.FlowLayout;
import
 java.awt.event.ActionEvent;
import
 java.awt.event.ActionListener;
import
 java.io.DataInputStream;
import
 java.io.DataOutputStream;
import
 java.io.File;
import
 java.io.IOException;
import
 java.io.RandomAccessFile;
import
 java.net.Socket;
import
 javax.swing.BoxLayout;
import
 javax.swing.JButton;
import
 javax.swing.JFileChooser;
import
 javax.swing.JFrame;
import
 javax.swing.JLabel;
import
 javax.swing.JOptionPane;
import
 javax.swing.JPanel;
import
 javax.swing.JProgressBar;
public class
 SendFile 
extends
 Thread{
  
private
 Socket socket=null;
  
private
 DataOutputStream dos;
  
private
 DataInputStream dis;
  
private
 RandomAccessFile rad;
  
private
 Container contentPanel;
      
private
 JFrame frame;
      
private
 JProgressBar progressbar;
      
private
 JLabel label;
  
public
 SendFile(){
    frame=
new
 JFrame("
文件传输
");
    
try
 {
          socket=new Socket("localhost", 8080);
     } 
catch
 (IOException e) {
     
 // TODO Auto-generated catch block
     e.printStackTrace();
      }
   }
  public void
 run(){
    JFileChooser fc = 
new
 JFileChooser();
   int status=fc.showOpenDialog(
null
);
    
if
 (status==JFileChooser.
APPROVE_OPTION
) {
    String 
path
=fc.getSelectedFile().getPath();
    try {
      dos=
new
 DataOutputStream(socket.getOutputStream());
      dis=
new
 DataInputStream(socket.getInputStream());
      dos.writeUTF("
ok
");
      rad=
new
 RandomAccessFile(path, "
r
");
      File file=
new
 File(path);
      byte[] buf=
new
 byte[1024];
      dos.writeUTF(file.getName());
      dos.flush();
      String rsp=dis.
readUTF
();
      
if
 (rsp.equals("ok")) {
          long size=dis.readLong();
//读取文件已发送的大小
         dos.writeLong(rad.length());
          dos.writeUTF("
ok
");
         dos.flush();
          long offset=size;
//字节偏移量
          int barSize=(int) (rad.length()/1024);
          int barOffset=(int)(offset/1024);
         
 //传输界面
         frame.setSize(380,120);
          contentPanel = frame.getContentPane();
          contentPanel.setLayout(
new
 BoxLayout(contentPanel, BoxLayout.
Y_AXIS
));
          progressbar = new JProgressBar();
//进度条
           label=new JLabel(file.getName()+" 
发送中
");
          contentPanel.add(label);
          progressbar.setOrientation(JProgressBar.
HORIZONTAL
);
          progressbar.setMinimum(0);
          progressbar.setMaximum(barSize);
          progressbar.setValue(barOffset);
              progressbar.setStringPainted(true);
              progressbar.setPreferredSize(
new
 Dimension(150, 20));
              progressbar.setBorderPainted(true);
              progressbar.setBackground(
Color
.pink);
              JButton cancel=
new
 JButton("
取消
");
              JPanel barPanel=
new
 JPanel();
              barPanel.setLayout(
new
 FlowLayout(FlowLayout.
LEFT
));
              barPanel.add(progressbar);
              barPanel.add(cancel);
              contentPanel.add(barPanel);    
              cancel.addActionListener(
new
 CancelActionListener());
          frame.setDefaultCloseOperation(
          JFrame.
EXIT_ON_CLOSE
);
          frame.setVisible(
true
);
         
 //从文件指定位置开始传输
          int length;
          
if
 (offset<rad.length()) {
             rad.seek(offset);
            
while
((length=rad.read(buf))>0){
               dos.write(buf,0,length);
              progressbar.setValue(++barOffset);
              dos.flush();
          }
         }
          label.setText(file.getName()+" 
发送完成
");
           }
      dis.close();
      dos.close();
      rad.close();
    } 
catch
 (IOException e) {
        
  // TODO Auto-generated catch block
      label.setText("
 取消发送,连接关闭
");
    }
finally
 {
      frame.dispose();
    }
  }
}
class
 CancelActionListener 
implements
 ActionListener{
  
public void
 actionPerformed(ActionEvent e3){
    
try
 {
      label.setText(" 
取消发送,连接关闭
");
      JOptionPane.showMessageDialog(frame, "
取消发送给,连接关闭!
", "
提示:
", JOptionPane.
INFORMATION_MESSAGE
);
      dis.close();
      dos.close();
      rad.close();
      frame.dispose();
      socket.close();
    } 
catch
 (IOException e1) {
   }
   }
 }
}

Receiver code:

import
 java.awt.Color;
import
 java.awt.Container;
import
 java.awt.Dimension;
import
 java.awt.FlowLayout;
import
 java.awt.event.ActionEvent;
import
 java.awt.event.ActionListener;
import
 java.io.DataInputStream;
import
 java.io.DataOutputStream;
import
 java.io.File;
import
 java.io.IOException;
import
 java.io.RandomAccessFile;
import
 java.net.ServerSocket;
import
 java.net.Socket;
import
 javax.swing.BoxLayout;
import
 javax.swing.JButton;
import
 javax.swing.JFrame;
import
 javax.swing.JLabel;
import
 javax.swing.JOptionPane;
import
 javax.swing.JPanel;
import
 javax.swing.JProgressBar;
public class
 ReceiveFile 
extends
 Thread{
  
private
 ServerSocket connectSocket=null;
  
private
 Socket socket=null;
  
private
 JFrame frame;
  
private
 Container contentPanel;
  
private
 JProgressBar progressbar;
  
private
 DataInputStream dis;
  
private
 DataOutputStream dos;
  
private
 RandomAccessFile rad;
  
private
 JLabel label;
   
public
 ReceiveFile(){
     frame=
new
 JFrame("
接收文件
");
    
try
 {
      connectSocket=
new
 ServerSocket(8080);
      socket=connectSocket.accept();
   } 
catch
 (IOException e) {
      
// TODO Auto-generated catch block
      e.printStackTrace();
   }
  }
   public void
 run(){
   try
 {
    dis=
new
 DataInputStream(socket.getInputStream());
    dos=
new
 DataOutputStream(socket.getOutputStream());
    dis.readUTF();
    int permit=JOptionPane.showConfirmDialog(frame, "
是否接收文件","文件传输请求:
", JOptionPane.
YES_NO_OPTION
);
    
if
 (permit==JOptionPane.
YES_OPTION
) {
      String filename=dis.
readUTF
();
      dos.writeUTF("
ok
");
      dos.flush();
      File file=
new
 File(filename+"
.temp
");
      rad=
new
 RandomAccessFile(filename+"
.temp
", "
rw
");
      
//获得文件大小
      long size=0;
      
if
(file.exists()
&&
 file.isFile()){
        size=file.length();
      }
      dos.writeLong(size);
//发送已接收的大小
      dos.flush();
      long allSize=dis.readLong();
      String rsp=dis.
readUTF
();
      
int
 barSize=(
int
)(allSize/1024);
      int barOffset=(
int
)(size/1024);
      
//传输界面
      frame.setSize(300,120);
      contentPanel =frame.getContentPane();
      contentPanel.setLayout(new 
BoxLayout
(contentPanel, BoxLayout.
Y_AXIS
));
      progressbar = 
new
 JProgressBar();
//进度条
      label=
new
 JLabel(filename+" 
接收中
");
      contentPanel.add(label);
      progressbar.setOrientation(JProgressBar.
HORIZONTAL
);
      progressbar.setMinimum(0);
      progressbar.setMaximum(barSize);
      progressbar.setValue(barOffset);
          progressbar.setStringPainted(true);
          progressbar.setPreferredSize(
new
 Dimension(150, 20));
          progressbar.setBorderPainted(
true
);
          progressbar.setBackground(
Color
.pink);
          JButton cancel=
new
 JButton("
取消
");
          JPanel barPanel=
new
 JPanel();
          barPanel.setLayout(new 
FlowLayout
(FlowLayout.
LEFT
));
          barPanel.add(progressbar);
          barPanel.add(cancel);
          contentPanel.add(barPanel);
          cancel.addActionListener(
new
 CancelActionListener());
          frame.setDefaultCloseOperation(
          JFrame.
EXIT_ON_CLOSE
);
          frame.setVisible(
true
);
          
//接收文件
      
if
 (rsp.equals("
ok
")) {
        rad.seek(size);
        int length;
        byte[] buf=
new
 byte[1024];
        while((length=dis.read(buf, 0, buf.length))!=-1){
          rad.write(buf,0,length);
          progressbar.setValue(++barOffset);
        }
        System.
out
.println("
FileReceive end...
");
      }
      label.setText(filename+" 
结束接收
");
      dis.close();
      dos.close();
      rad.close();
      frame.dispose();
      
//文件重命名
      
if
 (barOffset>=barSize) {
        file.renameTo(new File(filename));
       }
    }
else
{
      dis.close();
      dos.close();
      frame.dispose();
    }
    } 
catch
 (IOException e) {
      
// TODO Auto-generated catch block
      label.setText("
 已取消接收,连接关闭!
");
    }
finally
 {
      frame.dispose();
    }
  }
class
 CancelActionListener 
implements
 ActionListener{
  
public void
 actionPerformed(ActionEvent e){
    
try
 {
      dis.close();
      dos.close();
      rad.close();
      JOptionPane.showMessageDialog(frame, "
已取消接收,连接关闭!
", "
提示:
", JOptionPane.
INFORMATION_MESSAGE
);
      label.setText(" 
取消接收,连接关闭
");
    } 
catch
 (IOException e1) {
    }
   }
  }
}

Receiver test:

public class
 FileReceiveTest{
//接收方
  
public static void
 main(String[] args) {
    // TODO Auto-generated method stub 
    ReceiveFile rf=
new
 ReceiveFile();
    rf.start();
  }
}

Send Square test:

public class FileSendTest{
//发送方
  
public static void
 main(String[] args) {
    
// TODO Auto-generated method stub
    SendFile sf=new SendFile();
    sf.start();
  }
}

주의하세요. 수신자 코드를 먼저 실행한 다음 발신자 코드를 실행합니다. 테스트할 때 더 큰 파일을 선택했습니다. 여기에서 실행 결과는 다음과 같습니다.

먼저 Box를 수신할지 여부를 묻는 메시지가 표시됩니다.

받기를 시작하려면 예를 클릭하고, 취소하려면 아니요를 클릭하세요

이것이 성공적으로 끝났습니다!

위 내용은 파일의 중단점 재개 업로드를 구현하는 Java 소켓에 대한 자세한 소개(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제