Skip to content

Unnecessary FilterInputStream requirement in FileTypeDetector. #512

@garretwilson

Description

@garretwilson

I'm starting to try out your Metadata Extractor library. The first thing I want to do is detect the file type using FileTypeDetector:

public static FileType detectFileType(@NotNull final FilterInputStream inputStream) throws IOException

But why must I pass it a FilterInputStream? The standard approach is just to pass a plain old InputStream.

A FilterInputStream is simply a tool for creating a new input stream by "wrapping" an existing stream. (This is also referred to as the Decorator Design Pattern.) But that's an implementation detail. Why should detectFileType() care if I've wrapped an input stream or not?

Now if I have a perfectly good InputStream, in order to call detectFileType() I have to wrap it in a FilterInputStream, which serves no purpose because it's just a wrapper. You can look at the source code for FilterInputStream. It doesn't do anything more than the underlying InputStream does. Your detectFileType() gains absolutely no benefit—zero; no added functionality, and no guarantees—by requiring a FilterInputStream.

If we look at the documentation for detectFileType(), it says this:

    /**
     * …
     * Requires a {@link FilterInputStream} in order to mark and reset the stream to the position
     * at which it was provided to this method once completed.
     * …
     */

But this is not true. As we've seen FilterInputStream has nothing to do with whether mark and reset are supported; in fact whether a FilterInputStream supports mark/reset depends on the wrapped input stream.

The mark(int readlimit) and reset() methods are defined on the plain old InputStream class, so you could have (and should have) allowed any InputStream. But the only way to know whether the an input stream actually supports mark/reset is to call InputStream.markSupported() and see whether it returns true.

Your code does this check correctly. So why does it artificially require a completely irrelevant FilterInputStream requiring the caller to needlessly wrap a perfectly good InputStream?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions