文件傳輸java
㈠ java中如何實現從客戶端發送文件到伺服器端
伺服器端源碼:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/**
 *
 * 文件名:ServerReceive.java
 * 實現功能:作為伺服器接收客戶端發送的文件
 *
 * 具體實現過程:
 * 1、建立SocketServer,等待客戶端的連接
 * 2、當有客戶端連接的時候,按照雙方的約定,這時要讀取一行數據
 *      其中保存客戶端要發送的文件名和文件大小信息
 * 3、根據文件名在本地創建文件,並建立好流通信
 * 4、循環接收數據包,將數據包寫入文件
 * 5、當接收數據的長度等於提前文件發過來的文件長度,即表示文件接收完畢,關閉文件
 * 6、文件接收工作結束
public class ServerReceive {
 
    public static void main(String[] args) {
         
        /**與伺服器建立連接的通信句柄*/
        ServerSocket ss = null;
        Socket s = null;
         
        /**定義用於在接收後在本地創建的文件對象和文件輸出流對象*/
        File file = null;
        FileOutputStream fos = null;
         
        /**定義輸入流,使用socket的inputStream對數據包進行輸入*/
        InputStream is = null;
         
        /**定義byte數組來作為數據包的存儲數據包*/
        byte[] buffer = new byte[4096 * 5];
         
        /**用來接收文件發送請求的字元串*/
        String comm = null;
/**建立socekt通信,等待伺服器進行連接*/
        try {
            ss = new ServerSocket(4004);
            s = ss.accept();
        } catch (IOException e) {
            e.printStackTrace();
        }
/**讀取一行客戶端發送過來的約定信息*/
        try {
            InputStreamReader isr = new InputStreamReader(s.getInputStream());
            BufferedReader br = new BufferedReader(isr);
            comm = br.readLine();
        } catch (IOException e) {
            System.out.println("伺服器與客戶端斷開連接");
        }
         
        /**開始解析客戶端發送過來的請求命令*/
        int index = comm.indexOf("/#");
         
        /**判斷協議是否為發送文件的協議*/
        String xieyi = comm.substring(0, index);
        if(!xieyi.equals("111")){
            System.out.println("伺服器收到的協議碼不正確");
            return;
        }
         
        /**解析出文件的名字和大小*/
        comm = comm.substring(index + 2);
        index = comm.indexOf("/#");
        String filename = comm.substring(0, index).trim();
        String filesize = comm.substring(index + 2).trim();
/**創建空文件,用來進行接收文件*/
        file = new File(filename);
        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                System.out.println("伺服器端創建文件失敗");
            }
        }else{
            /**在此也可以詢問是否覆蓋*/
            System.out.println("本路徑已存在相同文件,進行覆蓋");
        }
         
        /**【以上就是客戶端代碼中寫到的伺服器的准備部分】*/
/**
         * 伺服器接收文件的關鍵代碼*/
        try {
            /**將文件包裝到文件輸出流對象中*/
            fos = new FileOutputStream(file);
            long file_size = Long.parseLong(filesize);
            is = s.getInputStream();
            /**size為每次接收數據包的長度*/
            int size = 0;
            /**count用來記錄已接收到文件的長度*/
            long count = 0;
             
            /**使用while循環接收數據包*/
            while(count < file_size){
                /**從輸入流中讀取一個數據包*/
                size = is.read(buffer);
                 
                /**將剛剛讀取的數據包寫到本地文件中去*/
                fos.write(buffer, 0, size);
                fos.flush();
                 
                /**將已接收到文件的長度+size*/
                count += size;
                System.out.println("伺服器端接收到數據包,大小為" + size);
            }
             
        } catch (FileNotFoundException e) {
            System.out.println("伺服器寫文件失敗");
        } catch (IOException e) {
            System.out.println("伺服器:客戶端斷開連接");
        }finally{
            /**
             * 將打開的文件關閉
             * 如有需要,也可以在此關閉socket連接
             * */
            try {
                if(fos != null)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }//catch (IOException e)
        }//finally
 
    }//public static void main(String[] args)
}//public class ServerReceive
客戶端源碼:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
/**
 *
 * 文件名:ClientSend.java
 * 實現功能:作為客戶端向伺服器發送一個文件
 *
 * 具體實現過程:
 * 1、建立與伺服器端的連接,IP:127.0.0.1, port:4004
 * 2、將文件的名字和大小通過自定義的文件傳輸協議,發送到伺服器
 * 3、循環讀取本地文件,將文件打包發送到數據輸出流中
 * 4、關閉文件,結束傳輸
 *
 * */
 
public class ClientSend {
 
    public static void main(String[] args) {
         
        /**與伺服器建立連接的通信句柄*/
        Socket s = null;
         
        /**定義文件對象,即為要發送的文件
         * 如果使用絕對路徑,不要忘記使用'/'和'\'的區別
         * 具體區別,請讀者自行查詢
         * */
        File sendfile = new File("API.CHM");
        /**定義文件輸入流,用來打開、讀取即將要發送的文件*/
        FileInputStream fis = null;
        /**定義byte數組來作為數據包的存儲數據包*/
        byte[] buffer = new byte[4096 * 5];
         
        /**定義輸出流,使用socket的outputStream對數據包進行輸出*/
        OutputStream os = null;
/**檢查要發送的文件是否存在*/
        if(!sendfile.exists()){
            System.out.println("客戶端:要發送的文件不存在");
            return;
        }
/**與伺服器建立連接*/
        try {
            s = new Socket("127.0.0.1", 4004);
        }catch (IOException e) {
            System.out.println("未連接到伺服器");
        }
         
        /**用文件對象初始化fis對象
         * 以便於可以提取出文件的大小
         * */
        try {
            fis = new FileInputStream(sendfile);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
/**首先先向伺服器發送關於文件的信息,以便於伺服器進行接收的相關准備工作
         * 具體的准備工作,請查看伺服器代碼。
         *
         * 發送的內容包括:發送文件協議碼(此處為111)/#文件名(帶後綴名)/#文件大小
         * */
        try {
            PrintStream ps = new PrintStream(s.getOutputStream());
            ps.println("111/#" + sendfile.getName() + "/#" + fis.available());
            ps.flush();
        } catch (IOException e) {
            System.out.println("伺服器連接中斷");
        }
/**
         * 此處睡眠2s,等待伺服器把相關的工作準備好
         * 也是為了保證網路的延遲
         * 讀者可自行選擇添加此代碼
         * */
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
/**之前的准備工作結束之後
         * 下面就是文件傳輸的關鍵代碼
         * */
        try {
             
            /**獲取socket的OutputStream,以便向其中寫入數據包*/
            os = s.getOutputStream();
             
            /** size 用來記錄每次讀取文件的大小*/
            int size = 0;
             
            /**使用while循環讀取文件,直到文件讀取結束*/
            while((size = fis.read(buffer)) != -1){
                System.out.println("客戶端發送數據包,大小為" + size);
                /**向輸出流中寫入剛剛讀到的數據包*/
                os.write(buffer, 0, size);
                /**刷新一下*/
                os.flush();
            }
        } catch (FileNotFoundException e) {
            System.out.println("客戶端讀取文件出錯");
        } catch (IOException e) {
            System.out.println("客戶端輸出文件出錯");
        }finally{
             
            /**
             * 將打開的文件關閉
             * 如有需要,也可以在此關閉socket連接
             * */
            try {
                if(fis != null)
                    fis.close();
            } catch (IOException e) {
                System.out.println("客戶端文件關閉出錯");
            }//catch (IOException e)
        }//finally
         
    }//public static void main(String[] args)
}//public class ClientSend
JSch支持三種文件傳輸模式:
 
OVERWRITE	完全覆蓋模式,這是JSch的默認文件傳輸模式,即如果目標文件已經存在,傳輸的文件將完全覆蓋目標文件,產生新的文件。
RESUME	
恢復模式,如果文件已經傳輸一部分,這時由於網路或其他任何原因導致文件傳輸中斷,如果下一次傳輸相同的文件,
則會從上一次中斷的地方續傳。
APPEND	追加模式,如果目標文件已存在,傳輸的文件將在目標文件後追加。
㈢ 用Java實現在兩台電腦之間的文件傳輸
使用Socket可以做到,不過直接編程一般都是在區域網內,如果要在不同區域網間通信,需要使用一台有公網IP的伺服器,可以電腦A和電腦B同時連接伺服器,然後A向伺服器傳遞文件,伺服器再將文件轉發電腦B。也可以使用打洞的方式使A、B互聯,此時伺服器的作用是輔助打洞。A、B向伺服器發送信息後socket不要關閉(假設使用10989埠),同時使用Serversocket綁定監聽相同的埠(監聽10989埠)。在java中有參數可以做到,具體方法請自行網路。伺服器獲取到A、B的外網地址和埠,將A的外網地址信息發送給B、將B的外網地址信息發送給A。然後使用A沒有關閉的Socket向B發送一組信息(此時連接會失敗,但是B的路由表上已經記錄了A的信息),發送後A向伺服器發送消息,伺服器告訴B A已經發送消息。然後B使用未關閉的socket向A發送消息,就和A上監聽的ServerSocket取得連接了。之後就可以互相傳遞數據。
㈣ java socket如何實現一次傳送多個文件
很簡單,就是把多個文件「變成」一個文件傳送就可以了,每個文件都是一個流,把這些流輸入到一個流中合並流傳輸即可,這個是基本思路。實現差不多以下兩個方法
1、直接流拼接,循環要傳輸的文件列表,多個InputStream,然後輸出到一個OutputStream,這個out就是發送數據的埠,為了接收端能夠識別每個文件從而分割流,需要每個流中結尾添加分隔符。其實這就是HTTP文件上傳的做法。
2、就比較簡單了,職業使用ZIP工具包吧需要傳輸的多文件壓縮成一個文件傳輸,接收端直接解壓縮就完事。
需要注意的是,發送多文件上傳你需要提取計算好總傳輸量位元組大小放在傳輸報文頭部告訴接收端你要發送的數據有多大,不然接收端可能無法完整接收數據。
