Java 網(wǎng)絡文件傳輸作者: 何雙江 關鍵字: Java 何雙江 IO NET File 讀者范圍: 本文是一篇簡短入門文章.本文假設讀者對Java的IO系統(tǒng)和Java的網(wǎng)絡系統(tǒng)有所了解. 正文: 關于文件傳輸?shù)膯栴},實際也是一種IO讀寫的基本問題.對于網(wǎng)絡而言也是一種IO讀寫問題.因此所謂網(wǎng)絡的文件傳輸實際是兩種IO問題的綜合討論.這里我們首先分析一個圖示.然后圍繞這個圖示來討論:
圖1: 分析圖1我們基本可以知道從服務器文件系統(tǒng)中通過流把文件中的數(shù)據(jù)寫入到服務器的進程中,然后把進程中的數(shù)據(jù)通過網(wǎng)絡IO系統(tǒng)傳遞到客戶機,這個階段,網(wǎng)絡中的數(shù)據(jù)以字節(jié)流的形式保存.當該字節(jié)流被客戶進程接受后,客戶進程通過客戶本地文件流寫入客戶本地的文件系統(tǒng)中. 根據(jù)以上分析,我們基本可以確定我所需要處理的問題了.首先我們需要可以對本地文件系統(tǒng)IO操作的操作接口,然后是一個可以對網(wǎng)絡IO系統(tǒng)進行操作的操作接口,已經(jīng)一個可以把數(shù)據(jù)包裝成字節(jié)流的操作接口,他們分別可以提供客戶和服務器兩個進程進行讀寫的操作.如下圖所示:
根據(jù)以上分析,我們可以把問題歸結到對以下編程接口的需求上: 1. 字節(jié)包裝器和字節(jié)解包器, 2. 網(wǎng)絡傳輸器和網(wǎng)絡接收器 3. 本地文件讀/寫器 而這些Java本身的API就已經(jīng)提供.他們都被包裝到java.io和java.net這兩個包里,這里我提供一個基于TCP/IP的實現(xiàn)版本,使用基于連接的方式來完成工作.我們首先介紹幾個相關的JDK中的類來完成以上任務, 1. DataOutputStream和DataInputStream實現(xiàn)類提供了上面的字節(jié)包裝和解包器的實現(xiàn) 2. ServerSocket和Socekt提供了基于連接的網(wǎng)絡傳輸和接受接口 3. File,FileInputStream和FileOutputStream提供了基本的本地文件輸入輸出接口. 服務器端實現(xiàn)代碼: import java.io.*; import java.net.*; public class FileServer{ public static void main(String[] args)throws Exception{ //創(chuàng)建文件流用來讀取文件中的數(shù)據(jù) File file=new File("lishengjie.jpg"); FileInputStream fos=new FileInputStream(file); //創(chuàng)建網(wǎng)絡服務器接受客戶請求 ServerSocket ss=new ServerSocket(3108); Socket client=ss.accept(); //創(chuàng)建網(wǎng)絡輸出流并提供數(shù)據(jù)包裝器 OutputStream netOut=client.getOutputStream(); OutputStream doc=new DataOutputStream(new BufferedOutputStream(netOut)); //創(chuàng)建文件讀取緩沖區(qū) byte[] buf=new byte[2048]; int num=fos.read(buf); while(num!=(-1)){//是否讀完文件 doc.write(buf,0,num);//把文件數(shù)據(jù)寫出網(wǎng)絡緩沖區(qū) doc.flush();//刷新緩沖區(qū)把數(shù)據(jù)寫往客戶端 num=fos.read(buf);//繼續(xù)從文件中讀取數(shù)據(jù) } fos.close(); doc.close(); } } 客戶方實現(xiàn)代碼: import java.io.*; import java.net.*; public class FileClient{ public static void main(String[] args)throws Exception{ //使用本地文件系統(tǒng)接受網(wǎng)絡數(shù)據(jù)并存為新文件 File file=new File("newFile.jpg"); file.createNewFile(); RandomAccessFile raf=new RandomAccessFile(file,"rw"); // 通過Socket連接文件服務器 Socket server=new Socket(InetAddress.getLocalHost(),3108); //創(chuàng)建網(wǎng)絡接受流接受服務器文件數(shù)據(jù) InputStream netIn=server.getInputStream(); InputStream in=new DataInputStream(new BufferedInputStream(netIn)); //創(chuàng)建緩沖區(qū)緩沖網(wǎng)絡數(shù)據(jù) byte[] buf=new byte[2048]; int num=in.read(buf); while(num!=(-1)){//是否讀完所有數(shù)據(jù) raf.write(buf,0,num);//將數(shù)據(jù)寫往文件 raf.skipBytes(num);//順序寫文件字節(jié) num=in.read(buf);//繼續(xù)從網(wǎng)絡中讀取文件 } in.close(); raf.close(); } } 歸結以上代碼:
總結: 事實上java的開發(fā)環(huán)境為我們提供大多數(shù)的編程接口,為我們簡化了開發(fā)工作量.我們通過java的IO接口所提供的文件,數(shù)據(jù)包裝器等接口非常方便的解決了我們上面的開發(fā)工作量.同時在java的net接口所提供的套接字也使得基于連接的數(shù)據(jù)接受和發(fā)送成為非常容易的工作. |
|
來自: yetao_study > 《Java》