那檔案傳輸呢:
一般提到 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 後續處理
...
}
沒有留言:
張貼留言