Heim  >  Artikel  >  Java  >  Detaillierte Einführung in Java Socket zur Implementierung der Breakpoint-Wiederaufnahmeübertragung von Dateien (Codebeispiel)

Detaillierte Einführung in Java Socket zur Implementierung der Breakpoint-Wiederaufnahmeübertragung von Dateien (Codebeispiel)

不言
不言nach vorne
2019-03-13 11:59:403697Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Einführung (Codebeispiel) zur Implementierung des Breakpoint-Resume-Uploads. Ich hoffe, dass er für Freunde hilfreich ist Du hast geholfen.

Da die Aufgabe mich, einen Java-Drecksack, erforderte, begann ich vor einiger Zeit zu lernen, wie man mit Java eine einfache Datei-Haltepunkt-Wiederaufnahmeübertragung implementiert. Mein Verständnis der sogenannten Dateifortsetzung ist, dass das Programm aus bestimmten Gründen nicht mehr ausgeführt wird und die Datei beendet wird. Wenn die Datei das nächste Mal erneut übertragen wird, kann die Datei von der letzten Übertragung übertragen werden Position, ohne sie erneut übertragen zu müssen.

Der Prozess der Dateiübertragung ist in den Absender und den Empfänger unterteilt. Letztendlich ist meine Idee wie folgt:

1: Bevor die Übertragung beginnt, sendet der Absender zunächst eine Bestätigungsnachricht an den Empfänger senden und dann den Dateinamen der zu sendenden Datei an den Empfänger senden
2: Nachdem der Empfänger die Bestätigungsnachricht erhalten hat, erhält er den vom Absender gesendeten Dateinamen. Nach dem Empfang sendet er eine Bestätigung Nachricht an den Absender, um anzuzeigen, dass der Dateiname empfangen wurde. Der Empfänger erstellt dann ein „.temp“-Dateiobjekt und ein „.temp“-RandomAccessFile-Objekt basierend auf dem empfangenen Dateinamen. Rufen Sie die Länge (Größe) der Datei ab, die diesem Dateiobjekt entspricht (diese Länge ist die Länge, die der Empfänger akzeptiert hat. Wenn die Datei noch nicht empfangen wurde, ist die Länge 0) und sendet die Dateilänge an den Absender.
3: Nachdem der Absender die Bestätigungsnachricht erhalten hat, empfängt er die vom Empfänger gesendete Dateilänge, sendet dann die Gesamtlänge der zu sendenden Datei an den Empfänger und sendet eine Bestätigungsnachricht an den Empfänger. Anschließend beginnt der Versand entsprechend der Länge der vom Empfänger gesendeten Datei an der Position, die der Länge der Datei entspricht.
4: Nach Erhalt der Bestätigungsnachricht akzeptiert der Empfänger die vom Absender gesendeten Daten und schreibt sie dann am Ende der Datei. Nachdem die Annahme abgeschlossen ist, benennen Sie die Datei „.temp“ in einen normalen Dateinamen um.

Zeichnen Sie den Prozess wie folgt:

Detaillierte Einführung in Java Socket zur Implementierung der Breakpoint-Wiederaufnahmeübertragung von Dateien (Codebeispiel)

die Unterbrechung erkennen kann Der Schlüssel zum Fortsetzen des Uploads ist die Verwendung von RandomAccessFile. Dieser Instanztyp unterstützt das Lesen und Schreiben von Direktzugriffsdateien.

Fügen Sie einige GUIs wie Fortschrittsbalken und Dateiauswahlen sowie den endgültigen Hauptcode hinzu 🎜>

Absendercode:

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) {
   }
   }
 }
}

Empfängercode:

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) {
    }
   }
  }
}

Empfängertest:

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

Absendertest:

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

Achten Sie darauf, dass das ausgeführt wird Zuerst den Empfängercode und dann den Absendercode. Ich habe hier eine Filmdatei ausgewählt. Die laufenden Ergebnisse sind wie folgt:

Zuerst wird angezeigt, ob der Empfang erfolgen soll oder nicht . Box

Klicken Sie auf Ja, um den Empfang zu starten, klicken Sie auf Nein, um den Vorgang abzubrechen

Dies wird erfolgreich abgeschlossen!

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Java Socket zur Implementierung der Breakpoint-Wiederaufnahmeübertragung von Dateien (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen