2013-10-24 77 views
3

我正在處理大文件,我需要圍繞base64有效載荷包裝XML。我的第一個幼稚實現將有效載荷作爲java.lang.String傳遞到[Velocity模板] [0]中,但對於大文件,我想用java.io.InputStream代替。我可以使用帶有InputStreams的Velocity模板嗎?

這裏是我的模板:

<?xml version="1.0" encoding="UTF-8"?> 
<Request> 
    <AdditonalParameters> 
#if($headers.additionalParameters) 
#foreach($key in $headers.additionalParameters.keySet()) 
     <Parameter> 
      <Key>${key}</Key> 
      <Value>${headers.additionalParameters.get($key)}</Value> 
     </Parameter> 
#end 
#end 
    </AdditonalParameters> 
    <Content>${body}</Content> 
</Request> 

$body可能會非常大,所以我想避免使用Stringbyte[]。是否有可能將InputStream作爲$body傳入我的模板中,或者我無法使用Velocity進行此操作?

回答

1

是的,這可以做到。所需要的是一個逐行打印您的InputString的迭代。由於速度缺乏while式的結構,只知道foreach循環,迭代會像在其最簡單的實現一個醜陋的黑客:

#foreach ($i in [0..100000]) 
    #set ($line = false) 
    #set ($line = $body.readLine()) 
    #if ($line) 
     ${line} 
    #else 
     #break 
    #end 
#end 

這裏一個非常大的數字範圍是用來模擬一個無限循環。當從InputStream$body)中不能再提取行時,循環將爲#break。一個需要注意的是第三行:

#set (line = $body.readLine()) 

一如往常,在速度,分配的左側時,右側的值不爲null不僅改變。由於$line永遠不會被指定爲空值,因此我們需要預先將其設置爲false(布爾值,而不是由readLine返回的字符串)。這樣,如果$line在第二個#set之後仍然是false,那麼我們知道readLine返回null,現在是退出迭代的時候了。

這種方法的一個問題是插入行之間的模板中有空白。有一些技巧可以避免這種情況(see here)。另外,可以通過創建一個Java List來避免0123x黑客,其iterator()方法返回Iterator,該代碼遍歷InputStream的行。這會少一些KISS,但它會使你的代碼更加可重用。

+0

這看起來很有希望,今天就試試看。 – cringe

相關問題