У меня есть сервлет, написанный на Java, который принимает отправленный файл в форме нескольких частей, который необходимо сохранить в MongoDb / GridFS. У меня уже есть код, работающий для этого.
Вот фрагмент кода, который показывает, как это делается с помощью пакета org.apache.commons.fileupload. Он почти не потребляет память, поскольку не хранит слишком много данных в памяти.
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(req);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
toProcess.put(name, Streams.asString(stream));
} else {
String fileName = item.getName();
String contentType = item.getHeaders().getHeader("Content-Type");
GridFSUploadOptions options = new GridFSUploadOptions()
// .chunkSizeBytes(358400)
.metadata(new Document("content_type", contentType));
ObjectId fileId = gridFSFilesBucket.uploadFromStream(fileName, stream, options);
fileIds.add(fileId);
fileNames.add(fileName);
}
Мне также нужно вычислить значения хэша sha1 для всех файлов. Apache digestutils может быть использован для этого. У него есть метод, который может вычислять sha1 в потоке:
https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html#sha1-java.io.InputStream-
Моя проблема в том, что этот метод полностью использует поток. Мне нужно разделить входной поток на две части. Введите одну часть в расчет SHA-1, а другую - в корзину GridFS.
Как я могу это сделать? Я думал о создании моей собственной "трубы", которая имеет входной и выходной потоки, пересылает все данные, но обновляет дайджест на лету.
Я просто не знаю, как начать писать такой канал.