- commons-fileupload框架源碼解析(一)--實(shí)例
- commons-fileupload框架源碼解析(二)--HTTP
- commons-fileupload框架源碼解析(三)--ParseRequest
- commons-fileupload框架源碼解析(四)--FileItemIterator
- commons-fileupload框架源碼解析(五)--MultipartStream
- commons-fileupload框架源碼解析(六)--ParameterParser
- commons-fileupload框架源碼解析(七)--FileCleaningTracker
- commons-fileupload框架源碼解析(八)--DeferredFileOutputStream
簡(jiǎn)介
DeferredFileOutputStream是一個(gè)根據(jù)設(shè)定的最大內(nèi)存閥值去控制寫入到內(nèi)存中,還是寫入到硬盤中畴蹭。
ThresholdingOutputStream
DeferredFileOutputStream繼承ThresholdOutputStream,ThresholdOutputStream繼承OuptStream,重寫了write相關(guān)方法轧叽。
ThresholdOutputStream.write相關(guān)方法
@Override
public void write(final int b) throws IOException
{
checkThreshold(1);
getStream().write(b);
written++;
}
@Override
public void write(final byte b[]) throws IOException
{
checkThreshold(b.length);
getStream().write(b);
written += b.length;
}
@Override
public void write(final byte b[], final int off, final int len) throws IOException
{
checkThreshold(len);
getStream().write(b, off, len);
written += len;
}
主要是加上了chekThreshold(len)方法罗洗,并調(diào)用getStream()交給另一個(gè)流
處理肛跌,并統(tǒng)計(jì)寫入了多少字節(jié)(written)艺配。
ThresholdOutputStream.checkThreshold(int)
protected void checkThreshold(final int count) throws IOException
{
if (!thresholdExceeded && written + count > threshold)
{
thresholdExceeded = true;
thresholdReached();
}
}
檢查當(dāng)前的寫入到內(nèi)容流的字節(jié)數(shù)written是否大于閥值threshold,大于的時(shí)候會(huì)調(diào)用thresholdReached()
getStream & thresholdReached
/**
* Returns the underlying output stream, to which the corresponding
* <code>OutputStream</code> methods in this class will ultimately delegate.
* 獲取輸出流
* @return The underlying output stream.
*
* @throws IOException if an error occurs.
*/
protected abstract OutputStream getStream() throws IOException;
/**
* Indicates that the configured threshold has been reached, and that a
* subclass should take whatever action necessary on this event. This may
* include changing the underlying output stream.
* 當(dāng)前的寫入字節(jié)數(shù)written是否大于閥值threshold時(shí)觸發(fā)
* @throws IOException if an error occurs.
*/
protected abstract void thresholdReached() throws IOException;
這兩個(gè)是抽象方法衍慎,而DeferredFileOutputStream重寫了,先看getStream
DeferredFileOutputStream.getStream
@Override
protected OutputStream getStream() throws IOException
{
return currentOutputStream;
}
返回currentOuputStream转唉,一開始默認(rèn)是內(nèi)存流ByteArrayOutputStream。
DeferredFileOutputStream.thresholdReached
@Override
protected void thresholdReached() throws IOException
{
//如果prefix,suffix,directory不為null稳捆,outputFile不管是否已經(jīng)引用了對(duì)象赠法,都會(huì)重新調(diào)用File.createTempFile(String,String,File)來(lái)
//創(chuàng)建指定的臨時(shí)文件,并讓后outputFile指向這個(gè)文件
if (prefix != null) {
//創(chuàng)建臨時(shí)文件
outputFile = File.createTempFile(prefix, suffix, directory);
}
FileUtils.forceMkdirParent(outputFile);//檢查父級(jí)目錄是否存在,不存在則創(chuàng)建砖织,創(chuàng)建父級(jí)文件目錄
final FileOutputStream fos = new FileOutputStream(outputFile);
try {
memoryOutputStream.writeTo(fos);//將已經(jīng)內(nèi)容流的數(shù)據(jù)寫入進(jìn)文件流
} catch (final IOException e){
fos.close();//當(dāng)前出現(xiàn)異常時(shí)關(guān)閉流款侵,并拋出異常
throw e;
}
currentOutputStream = fos;
memoryOutputStream = null;
}
當(dāng)達(dá)到閥值的時(shí)候,thresholdReached()就會(huì)被調(diào)用侧纯,會(huì)將內(nèi)存流memoryOutputStream中的數(shù)據(jù)轉(zhuǎn)換到寫入硬盤的流FileOuputStream中新锈,并將FileOuputStream重新賦值currentOuptputStream