Ce que cet article vous apporte est une introduction détaillée à l'implémentation de la reprise de fichiers dans Java Socket (exemples de code). Les amis dans le besoin peuvent s'y référer. J'espère que cela vous sera utile. .
Il y a quelque temps, parce que la tâche m'exigeait, un salaud de Java, j'ai commencé à étudier comment utiliser Java pour implémenter un simple transfert de reprise de point d'arrêt de fichier. Ma compréhension de la soi-disant reprise de fichier est que lorsque le fichier est transféré pour certaines raisons, le programme s'arrête et le fichier est terminé. Lorsque le fichier est retransmis la prochaine fois, le fichier peut être transféré à partir du dernier transfert. position sans avoir à la retransmettre. Repartir de zéro.
Le processus de transfert de fichiers est divisé entre l'expéditeur et le destinataire. Au final, mon idée est la suivante :
1 : Avant le début du transfert, l'expéditeur envoie d'abord un message de confirmation. au destinataire, puis envoyez le nom du fichier à envoyer au destinataire
2 : Une fois que le destinataire a reçu le message de confirmation, il reçoit le nom du fichier envoyé par l'expéditeur. Après l'avoir reçu, il envoie une confirmation. message à l'expéditeur pour indiquer que le nom du fichier a été reçu. Le destinataire crée ensuite un objet File ".temp" et un objet RandomAccessFile ".temp" en fonction du nom de fichier reçu. Récupère la longueur (taille) du fichier correspondant à cet objet File (cette longueur est la longueur que le destinataire a acceptée. Si le fichier n'a pas été reçu auparavant, la longueur est 0), et envoie la longueur du fichier à l'expéditeur.
3 : Une fois que l'expéditeur a reçu le message de confirmation, il reçoit la longueur du fichier envoyé par le destinataire, puis envoie la longueur totale du fichier à envoyer au destinataire et envoie un message de confirmation au destinataire. Puis en fonction de la longueur du fichier envoyé par le destinataire, l'envoi démarre à la position correspondant à la longueur du fichier.
4 : Après avoir reçu le message de confirmation, le destinataire accepte les données envoyées par l'expéditeur, puis les écrit à la fin du fichier. Une fois l'acceptation terminée, renommez le fichier ".temp" en un nom de fichier normal.
Dessinez le processus comme suit :
peut réaliser l'interruption. La clé pour cliquer sur Reprendre est d'utiliser RandomAccessFile. Ce type d'instance prend en charge la lecture et l'écriture de fichiers à accès aléatoire
Ajoutez des interfaces graphiques telles que des barres de progression et des sélecteurs de fichiers, ainsi que le code principal final :
Code expéditeur :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) { } } } }Code récepteur :
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) { } } } }Test récepteur :
public class FileReceiveTest{ //接收方 public static void main(String[] args) { // TODO Auto-generated method stub ReceiveFile rf= new ReceiveFile(); rf.start(); } }Test expéditeur :
public class FileSendTest{ //发送方 public static void main(String[] args) { // TODO Auto-generated method stub SendFile sf=new SendFile(); sf.start(); } }Notez que vous exécutez d'abord le code du destinataire, puis le code de l'expéditeur. Lors du test, nous choisissons un fichier plus volumineux ici. Les résultats d'exécution sont les suivants : Il y aura d'abord un. boîte de dialogue demandant si vous souhaitez recevoir Cliquez sur oui pour commencer à recevoir, cliquez sur non pour annuler Cela se termine avec succès !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!