How to get the magic number from File in java

user1012506 picture user1012506 · Dec 18, 2016 · Viewed 7.5k times · Source

I have file from UploadedFile button, and I want to print the extension files by use in magic number,

My code:

UploadedFile file = (UploadedFile)valueChangeEvent.getNewValue();
byte[] fileByteArray = IOUtils.toByteArray(file.getInputStream());

pay attention: Mime type and content file (from file and from the filename) not same to magic number (magic number comes from the first bytes of the inputStream)

How can I do it?

Answer

Dewa Syahrizal MN picture Dewa Syahrizal MN · Dec 31, 2019

I know this is an old question, just put my answer here hopefully someone finds it useful when searching for the same solution.

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import javax.servlet.annotation.MultipartConfig;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@MultipartConfig(
    fileSizeThreshold = 0,
    maxFileSize = 1024 * 1024 * 50,       // 50MB
    maxRequestSize = 1024 * 1024 * 100)   // 100MB
public class FileUpload extends HttpServlet {    

    private static final Logger logger = LogManager.getLogger(FileUpload.class);
    private byte[] data = new byte[4];

    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {

        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");

        try {
            fileSignature(request
              .getPart("image_file")
              .getInputStream());
        } catch (IOException | NullPointerException ex) {
            logger.error(ex);
        }

        String fileType = getFileType(data);

        // return the recognized type 
        response.getWriter().write(fileType);
    }

    /**
     * Get the first 4 byte of a file file signature. 
     * 
     * @param part File from part.
     */
     private void fileSignature(InputStream is)
             throws IOException, NullPointerException {
         is.read(data, 0, 4);
     }

     /**
      * Get the file type based on the file signature.
      * Here restricted to only recognized file type jpeg, jpg, png and
      * pdf where the signature of jpg and jpeg files are the same.
      *
      * @param fileData Byte array of the file.
      * @return String of the file type.
      */
     private String getFileType(byte[] fileData) {
         String type = "undefined";
         if(Byte.toUnsignedInt(fileData[0]) == 0x89 && Byte.toUnsignedInt(fileData[1]) == 0x50)
             type = "png";
         else if(Byte.toUnsignedInt(fileData[0]) == 0xFF && Byte.toUnsignedInt(fileData[1]) == 0xD8)
             type = "jpg";
         else if(Byte.toUnsignedInt(fileData[0]) == 0x25 && Byte.toUnsignedInt(fileData[1]) == 0x50)
             type = "pdf";

        return type;
    }
}

References for file magic numbers: