首页 > 解决方案 > 使用 ApacheTika 检测文件扩展名会损坏文件

问题描述

我正在尝试检测作为 InputStream 传递的文件的文件扩展名,扩展名被正确检测到,但此后文件往往会损坏。这是我检测扩展的方法-

public static Optional<String> detectFileExtension(InputStream inputStream) {

    // To provide mark/reset functionality to the stream required by Tika.
    InputStream bufferedInputStream = new BufferedInputStream(inputStream);

    String extension = null;
    try {
        MimeTypes mimeRepository = getMimeRepository();

        MediaType mediaType = mimeRepository.detect(bufferedInputStream, new Metadata());
        MimeType mimeType = mimeRepository.forName(mediaType.toString());
        extension = mimeType.getExtension();
        log.info("File Extension detected: {}", extension);

        // Need to reset input stream pos marker since it was updated while detecting the extension
        inputStream.reset();
        bufferedInputStream.close();

    } catch (MimeTypeException | IOException ignored) {
        log.error("Unable to detect extension of the file from the provided stream");
    }
    return Optional.ofNullable(extension);
}

private static MimeTypes getMimeRepository() {
    TikaConfig config = TikaConfig.getDefaultConfig();
    return config.getMimeRepository();
}

现在,当我尝试在扩展检测后再次使用相同的 InputStream 保存此文件时 -

byte[] documentContentByteArray = IOUtils.toByteArray(inputStream);

Optional<String> extension = FileTypeHelper.detectFileExtension(inputStream);
    if (extension.isPresent()) {
        fileName = fileName + extension.get();
    } else {
        log.warn("File: {} does not have a valid extension", fileName);         
    }
File file = new File("/tmp/" + fileName);
FileUtils.writeByteArrayToFile(file, documentContentByteArray);

它会创建一个文件,但文件已损坏。我猜在 detectFileExtension 中的流消耗后,流没有正确重置。如果有人在一些指导之前已经这样做了,那就太好了,在此先感谢。

标签: javaapacheinputstreamapache-tika

解决方案


我通过不一次又一次地使用相同的输入流来修复它。我创建了一个新流来传递扩展检测和创建文件的初始流。

byte[] documentContentByteArray = IOUtils.toByteArray(inputStream);

//extension detection
InputStream extensionDetectionInputStream = new ByteArrayInputStream(documentContentByteArray);
Optional<String> extension = FileTypeHelper.detectFileExtension(inputStream);
    if (extension.isPresent()) {
        fileName = fileName + extension.get();
    } else {
        log.warn("File: {} does not have a valid extension", fileName);
    }
extensionDetectionInputStream.close();

//File creation
File file = new File("/tmp/" + fileName);
FileUtils.writeByteArrayToFile(file, documentContentByteArray);

如果有更好的方法可以通过重用相同的流来做到这一点,那就太好了,我很乐意接受这个答案,现在,我将其标记为已接受的答案。


推荐阅读