【问题标题】:How do I know if a File type is PDF?我如何知道文件类型是否为 PDF?
【发布时间】:2012-10-29 02:46:37
【问题描述】:
  • 这个答案How can I determine if a file is a PDF file?建议下载另一个库,但我的要求是我只需要检查文件目录是否为PDF类型

  • 为此使用完整的库看起来有点矫枉过正

  • 有什么方法可以知道 Java 文件是 PDF 类型的吗?

【问题讨论】:

标签: java pdf


【解决方案1】:

好吧,根据wikipedia PDF 文件以幻数开头:"%PDF" (hex 25 50 44 46) 所以也许你应该检查文件中的 InputStream 并检查。

【讨论】:

  • 刚刚在 notepad++ 中打开了一个 PDF,确实如此。 +1
  • 是的,我有一个类似的用例,维基百科很有帮助
  • 但是如果你制作一个文本文件,并以 %PDF-1.4 开头,只是为了搞砸操作
  • @SamIam - 听起来像是另一个支持使用库的论点。
  • 没错,因为这种事情我会用一个库,比如apache Tika、PRONOM DROID、JHove或者任何其他的识别工具,因为他们不仅看签名,而且看整体格式和尾随字节,并为您提供 MIME、格式和版本等特定信息。
【解决方案2】:

SimpleMagic 是一个用于解析内容类型的 Java 库:

<!-- pom.xml -->
    <dependency>
        <groupId>com.j256.simplemagic</groupId>
        <artifactId>simplemagic</artifactId>
        <version>1.8</version>
    </dependency>

import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.j256.simplemagic.ContentType;
// ...

public class SimpleMagicSmokeTest {

    private final static Logger log = LoggerFactory.getLogger(SimpleMagicSmokeTest.class);

    @Test
    public void smokeTestSimpleMagic() throws IOException {
        ContentInfoUtil util = new ContentInfoUtil();
        File possiblePdfFile = new File("/path/to/possiblePdfFile.pdf");
        ContentInfo info = util.findMatch(possiblePdfFile);

        log.info( info.toString() );
        assertEquals( ContentType.PDF, info.getContentType() );
    }

【讨论】:

    【解决方案3】:

    好吧,一种骇人听闻的解决方案是查看完整的文件名,看看它是否以“.pdf”结尾。以下应该会有所帮助:

    import javax.activation.*;  
    
    public class ShowMimeType  
    {  
        public static void main(String[] args) {  
            FileDataSource ds = new FileDataSource(args[0]);  
            String contentType = ds.getContentType();  
            System.out.println("The MIME type of the file " + args[0] + " is: " + contentType);  
        }  
    }  
    

    【讨论】:

      【解决方案4】:

      如果检查文件扩展名不满意,您可以尝试通过读取文件的几个字节来检查文件magic number

      PDF files start with "%PDF" (hex 25 50 44 46).
      

      【讨论】:

        【解决方案5】:

        结合了较轻的 URLCONnection.guessContentTypeFromStream(),它为某些 mimeTypes 返回 null,与较重的 AutoDetectParser。

        if(currentImageType ==null){
                        ByteArrayInputStream is = new ByteArrayInputStream(image);
                        String mimeType = URLConnection.guessContentTypeFromStream(is);
                        if(mimeType == null){
                            AutoDetectParser parser = new AutoDetectParser();
                            Detector detector = parser.getDetector();
                            Metadata md = new Metadata();
                            mimeType = detector.detect(is,md).toString();
        
                            if (mimeType.contains("pdf")){
                                mimeType ="pdf";
                            }
                            else if(mimeType.contains("tif")||mimeType.contains("tiff")){
                                mimeType = "tif";
                            }
                        }
                        if(mimeType.contains("png")){
                            mimeType ="png";
                        }
                        else if( mimeType.contains("jpg")||mimeType.contains("jpeg")){
                            mimeType = "jpg";
                        }
                        else if (mimeType.contains("pdf")){
                            mimeType ="pdf";
                        }
                        else if(mimeType.contains("tif")||mimeType.contains("tiff")){
                            mimeType = "tif";
                        }
        
                        currentImageType = ImageType.fromValue(mimeType);
                    }
        

        【讨论】:

          【解决方案6】:

          尝试了下面的代码,它成功了。

          public static boolean isSelectedFilePdf(Uri uri, ContentResolver contentResolver) {
          if (uri != null) {
                  if (uri.getScheme().equals("content")) {
                      String type = contentResolver.getType(uri);
                      return type != null && type.startsWith("application/pdf");
                  } else {
                      String fileName = uri.getLastPathSegment();
                      String extension = fileName.substring(fileName.lastIndexOf("."));
                      return extension != null && extension.equalsIgnoreCase(".pdf");
                  }
              }
          }
          

          【讨论】:

            【解决方案7】:

            Check whether a PDF-File is valid (Python)提到了以下解决方案

            在我的项目中,我需要检查某些上传文件的 mime 类型。我只是像这样使用文件命令:

            from subprocess import Popen, PIPE
            filetype = Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, stdin=PIPE).communicate(file.read(1024))[0].strip()
            

            您当然可能希望将实际命令移动到某个配置文件中,因为命令行选项也因操作系统(例如 mac)而异。

            如果您只需要知道它是否是 PDF 并且无论如何都不需要处理它,我认为 file 命令是比 lib 更快的解决方案。当然也可以手动进行,但如果您想检查不同的类型,文件命令可能会为您提供更大的灵活性。

            【讨论】:

              【解决方案8】:

              这听起来有点太明显了,但请检查文件名的扩展名。

              如果它对探索者来说足够好,它应该对你来说足够好

              【讨论】:

              • @peshkira 好吧,应该这样。只有极少数情况下你不能相信它。
              • 您发表评论的依据是什么。怎么能说很少呢?这取决于用例。你说它很少,因为你可能不这样做或没有遇到它,但这并不意味着它不会发生在现实世界的场景中。
              • 我会说将设计决策基于 Microsoft Explorer 做事的方式是一个坏主意......我认为大多数人都会同意 Windows 并不完美(并且远非如此)。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-09-15
              • 2010-11-07
              • 2015-04-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多