您可以使用反射來訪問FilterOutputStream
的os.out場,這可是有一些缺點:
- 如果對方的OutputStream也是一種RolloverOutputStream的,你可以有一個很難重建它,
- 如果其他的OutputStream具有自定義設置,如Gzip壓縮參數,你可以不可靠的閱讀
- 如果有
一個快速和骯髒的實施recreateChainedOutputStream(
可能是:
private final static Field out;
{
try {
out = FilterInputStream.class.getField("out");
out.setAccessible(true);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public OutputStream recreateChainedOutputStream(OutputStream out) throws IOException {
if (out instanceof FilterOutputStream) {
Class<?> c = ou.getClass();
COnstructor<?> con = c.getConstructor(OutputStream.class);
return con.invoke(this.out.get(out));
} else {
// Other output streams...
}
}
雖然這可能是當前應用程序確定,這是一個很大的禁忌在生產世界,因爲大量不同種類的OutputStreams您的應用程序的可能會收到。
解決問題的更好方法是一種Function<String, OutputStream>
,它可以作爲工廠爲指定文件創建OutputStream
。通過這種方式,外部api可以控制OutputStream
,而您的api可以處理多個文件名。這方面的一個例子是:
public class MyApi {
private final Function<String, OutputStream> fileProvider;
private OutputStream current;
public MyApi (Function<String, OutputStream> fileProvider, String defaultFile) {
this.fileProvider = fileProvider;
selectNewOutputFile(defaultFile);
}
public void selectNewOutputFile(String name) {
OutputStream current = this.current;
this.current = fileProvider.apply(name);
if(current != null) current.close();
}
}
這然後可以在其它應用中被用作:
MyApi api = new MyApi(name->new FileOutputStream(name));
對於簡單FileOutputStream
S,或可以用作:
MyApi api = new MyApi(name->
new GZIPOutputStream(
new CipherOutputStream(
new CheckedOutputStream(
new FileOutputStream(name),
new CRC32()),
chipper),
1024,
true)
);
對於文件流存儲校驗和使用new CRC32()
,使用chipper
切片,gzip根據具有同步寫入模式的1024緩衝區。
看起來像是X-Y問題。爲什麼這需要? – Ferrybig
我想編寫一個RolloverOutputStream,它可以自己滾動文件,其中消費者類應該能夠通過傳入基礎OutputStream(可以是FileOutputStream上的GZipOutputStream或普通的FileOutputStream或更多的組合)以及閾值應該在哪些文件上滾動。消費應用程序應該能夠無限期地繼續寫入,而RolloverOutputStream在數據大小超過閾值時處理翻轉。 – rajeshnair
如果你想創建一個'RolloverOutputStream',創建'OutputStream'的自定義實現將會更容易,該實現有'setOutputStream()'方法來選擇它的目標。您當前的解決方案依賴於輸出流是鏈的頂端的事實,在所有應用中可能並非總是如此。 – Ferrybig