那檔案傳輸呢:
一般提到 Java I/O 時,很多的 software developer 並不會對它陌生;遇到 HTTP 的檔案傳輸可使用如 Apache HTTPClient 這樣子的 package,以 multi-part 方式 (MultipartEntity) 來傳輸。
但個人有遇過 "咬" 住的測試經驗。於是乎搬出 PipedInputStream / PipedOutputStream 再加上啟用一個 Thread 來處理,就可以解決這個問題了。以 Groovy 為例:
... def InputStream pipeOutput(Closure write) { def output = new PipedOutputStream() def input = new PipedInputStream(output) Thread.start { try{ write(output) output.flush() } finally { try { output?.close() } catch (e) {/*nothing to do*/} } } return input } ... ... def ctn = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE) ctn.addPart("zipFile", new InputStreamBody( pipeOutput { output -> Thread.currentThread().sleep(1000) inFile = new FileInputStream(fileName) output << inFile } ,'application/x-gzip' ,'test.gz' ) ) ... ... // HttpClient的處理 <略> ...@@ (暈了嗎?)
那 RMI 呢? (想到就頭大?)
還好有 RMIIO 這個好心的 package (是 LGPL 哦,感動吧!感謝作者)
它的優點,就是如同它的說明所描述: makes it as simple as possible to stream large amounts of data
我個人使用它的心得是,沒有 "咬" 住的情形。而且當初看上它的原因是 client code 與 server code 之間,不需要做 nofity 與 ack 這樣多餘的機制來傳檔與送回接到檔案的訊息:
A --- send ---> B
A <--- ack --- B
只要控制是否 throw RemoteException 以及 try / catch 這個 exception 即可。以 Java code 為例:
// 傳送端 // 用壓縮的 InputStream try { ... RemoteInputStream remoteIs = exporter.export(new GZIPRemoteInputStream(fileInputStream)); ... remoteObject.receiveData(remoteIs); ... } catch ... ...
// 接收端 public void receiveData(RemoteInputStream remoteIs) throws RemoteException { ... InputStream is = RemoteInputStreamClient.wrap(remoteIs); ... if (somethingWrong) throw new RemoteException("some message"); ... // InputStream / OutputStream 後續處理 ... }
沒有留言:
張貼留言