關於檔案傳輸的問題,實際也是一種IO讀寫的基本問題.對於網路而言也是一種IO讀寫問題.因此所謂網路的檔案傳輸實際是兩種IO問題的綜合討論.這裡我們首先分析一個圖示.然後圍繞這個圖示來討論:
圖1:
分析圖1我們基本可以知道從伺服器檔案系統中通過流把檔案中的資料寫入到伺服器的進程中,然後把進程中的資料通過網路IO系統傳遞到客戶機,這個階段,網路中的資料以位元組流的形式儲存.當該位元組流被客戶進程接受後,客戶進程通過客戶本地檔案流寫入客戶本地的檔案系統中.
根據以上分析,我們基本可以確定我所需要處理的問題了.首先我們需要可以對本地檔案系統IO操作的操作介面,然後是一個可以對網路IO系統進行操作的操作介面,已經一個可以把資料封裝成位元組流的操作介面,他們分別可以提供客戶和伺服器兩個進程進行讀寫的操作.如所示:
圖2:
根據以上分析,我們可以把問題歸結到對以下編程介面的需求上:
1. 位元組封裝器和位元組解包器,
2. 網路傳輸器和網路接收器
3. 本地檔案讀/寫器
而這些Java本身的API就已經提供.他們都被封裝到java.io和java.net這兩個包裡,這裡我提供一個基於TCP/IP的實現版本,使用基於串連的方式來完成工作.我們首先介紹幾個相關的JDK中的類來完成以上任務,
1. DataOutputStream和DataInputStream實作類別提供了上面的位元組封裝和解包器的實現
2. ServerSocket和Socekt提供了基於串連的網路傳輸和接受介面
3. File,FileInputStream和FileOutputStream提供了基本的本地檔案輸入輸出介面.
伺服器端實現代碼:
import java.io.*;
import java.net.*;
public class FileServer{
public static void main(String[] args)throws Exception{
//建立檔案流用來讀取檔案中的資料
File file=new File("lishengjie.jpg");
FileInputStream fos=new FileInputStream(file);
//建立網路伺服器接受客戶請求
ServerSocket ss=new ServerSocket(3108);
Socket client=ss.accept();
//建立網路輸出資料流並提供資料封裝器
OutputStream netOut=client.getOutputStream();
OutputStream doc=new DataOutputStream(new BufferedOutputStream(netOut));
//建立檔案讀取緩衝區
byte[] buf=new byte[2048];
int num=fos.read(buf);
while(num!=(-1)){//是否讀完檔案
doc.write(buf,0,num);//把檔案資料寫出網路緩衝區
doc.flush();//重新整理緩衝區把資料寫往用戶端
num=fos.read(buf);//繼續從檔案中讀取資料
}
fos.close();
doc.close();
}
}
客戶方實現代碼:
import java.io.*;
import java.net.*;
public class FileClient{
public static void main(String[] args)throws Exception{
//使用本地檔案系統接受網路資料並存為新檔案
File file=new File("newFile.jpg");
file.createNewFile();
RandomAccessFile raf=new RandomAccessFile(file,"rw");
// 通過Socket串連檔案伺服器
Socket server=new Socket(InetAddress.getLocalHost(),3108);
//建立網路接受流接受伺服器檔案資料
InputStream netIn=server.getInputStream();
InputStream in=new DataInputStream(new BufferedInputStream(netIn));
//建立緩衝區緩衝網路資料
byte[] buf=new byte[2048];
int num=in.read(buf);
while(num!=(-1)){//是否讀完所有資料
raf.write(buf,0,num);//將資料寫往檔案
raf.skipBytes(num);//順序寫檔案位元組
num=in.read(buf);//繼續從網路中讀取檔案
}
in.close();
raf.close();
}
}
歸結以上代碼:
伺服器 用戶端
1. 伺服器從本地檔案系統讀取檔案
2. 伺服器建立網路服務串連
3. 伺服器提供資料封裝器
4. 伺服器將本地檔案寫入資料封裝器
5. 伺服器通過封裝器寫入到網路 1. 用戶端建立新檔案準備儲存來自網路的資料
2. 用戶端串連伺服器
3. 用戶端通過網路接受伺服器資料並進行資料解包
4. 用戶端將資料寫入緩衝區
5. 用戶端從緩衝區把資料寫入客戶本地檔案
總結:
事實上java的開發環境為我們提供大多數的編程介面,為我們簡化了開發工作量.我們通過java的IO介面所提供的檔案,資料封裝器等介面非常方便的解決了我們上面的開發工作量.同時在java的net介面所提供的通訊端也使得基於串連的資料接受和發送成為非常容易的工作.