Вы можете использовать отражение для доступа к os.out поле FilterOutputStream
, это, однако, имеет некоторые недостатки:
- Если другой 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
s для названного файла. Таким образом, внешний api сохраняет свой контроль над OutputStream
s, в то время как ваш 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
с, или использоваться в качестве:
MyApi api = new MyApi(name->
new GZIPOutputStream(
new CipherOutputStream(
new CheckedOutputStream(
new FileOutputStream(name),
new CRC32()),
chipper),
1024,
true)
);
For A файловый поток, который хранится с контрольной суммой с использованием new CRC32()
, скопирован с использованием chipper
, gzip в соответствии с 1024 буфером с режимом записи в режиме синхронизации.
Кажется, проблема X-Y. Почему это необходимо? – Ferrybig
Я хочу написать RolloverOutputStream, который может сворачивать файлы сам по себе, когда потребительские классы должны быть в состоянии создать это, передав базовый OutputStream (который может быть GZipOutputStream через FileoutStream или простой FileOutputStream или еще какая-то комбинация этого) вместе с порогом при котором файлы должны быть перевернуты. Потребляющее приложение должно иметь возможность продолжать писать неограниченное время, в то время как RolloverOutputStream обрабатывает опрокидывание, когда размер данных пересекает порог. – rajeshnair
Если вы хотите создать «RolloverOutputStream», было бы проще создать пользовательскую реализацию 'OutputStream', которая имеет метод' setOutputStream() 'для выбора своей цели. Ваше текущее решение основывается на том, что выходной поток является вершиной цепочки, что не всегда верно для всех приложений. – Ferrybig