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:
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) { } } } }
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) { } } } }
public class FileReceiveTest{ //接收方 public static void main(String[] args) { // TODO Auto-generated method stub ReceiveFile rf= new ReceiveFile(); rf.start(); } }
public class FileSendTest{ //发送方 public static void main(String[] args) { // TODO Auto-generated method stub SendFile sf=new SendFile(); sf.start(); } }
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!