Asc*_*ian 1 java string comparison
在我的公司,出于其他原因,我需要将mime类型与文件扩展名进行比较。我有一个CommonsMultipartFile。我正在尝试找出进行此比较的最佳方法。我已经看到了MimetypesFileTypeMap,但不确定是否可以在这里使用。我试图避免(或限制)任何硬编码。
我得到这样的值:
CommonsMultipartFile file = ...;
String fileName = file.getOriginalFilename();
String contentType = file.getContentType();
String extension = FilenameUtils.getExtension(fileName);
Run Code Online (Sandbox Code Playgroud)
感谢您的指导和帮助。谢谢!
这种情况下的Java库非常有限(类型数)。这是我的方法:
static String getMimeType(String fileName) {
// 1. first use java's built-in utils
FileNameMap mimeTypes = URLConnection.getFileNameMap();
String contentType = mimeTypes.getContentTypeFor(fileName);
// 2. nothing found -> lookup our in extension map to find types like ".doc" or ".docx"
if (contentType == null) {
String extension = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length());;
contentType = fileExtensionMap.get(extension);
}
return contentType;
}
Run Code Online (Sandbox Code Playgroud)
第2步涉及一张静态地图:
private static final Map<String, String> fileExtensionMap;
static {
fileExtensionMap = new HashMap<String, String>();
// MS Office
fileExtensionMap.put("doc", "application/msword");
fileExtensionMap.put("dot", "application/msword");
fileExtensionMap.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
fileExtensionMap.put("dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template");
fileExtensionMap.put("docm", "application/vnd.ms-word.document.macroEnabled.12");
fileExtensionMap.put("dotm", "application/vnd.ms-word.template.macroEnabled.12");
fileExtensionMap.put("xls", "application/vnd.ms-excel");
fileExtensionMap.put("xlt", "application/vnd.ms-excel");
fileExtensionMap.put("xla", "application/vnd.ms-excel");
fileExtensionMap.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
fileExtensionMap.put("xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template");
fileExtensionMap.put("xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12");
fileExtensionMap.put("xltm", "application/vnd.ms-excel.template.macroEnabled.12");
fileExtensionMap.put("xlam", "application/vnd.ms-excel.addin.macroEnabled.12");
fileExtensionMap.put("xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12");
fileExtensionMap.put("ppt", "application/vnd.ms-powerpoint");
fileExtensionMap.put("pot", "application/vnd.ms-powerpoint");
fileExtensionMap.put("pps", "application/vnd.ms-powerpoint");
fileExtensionMap.put("ppa", "application/vnd.ms-powerpoint");
fileExtensionMap.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
fileExtensionMap.put("potx", "application/vnd.openxmlformats-officedocument.presentationml.template");
fileExtensionMap.put("ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow");
fileExtensionMap.put("ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12");
fileExtensionMap.put("pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12");
fileExtensionMap.put("potm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12");
fileExtensionMap.put("ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12");
// Open Office
fileExtensionMap.put("odt", "application/vnd.oasis.opendocument.text");
fileExtensionMap.put("ott", "application/vnd.oasis.opendocument.text-template");
fileExtensionMap.put("oth", "application/vnd.oasis.opendocument.text-web");
fileExtensionMap.put("odm", "application/vnd.oasis.opendocument.text-master");
fileExtensionMap.put("odg", "application/vnd.oasis.opendocument.graphics");
fileExtensionMap.put("otg", "application/vnd.oasis.opendocument.graphics-template");
fileExtensionMap.put("odp", "application/vnd.oasis.opendocument.presentation");
fileExtensionMap.put("otp", "application/vnd.oasis.opendocument.presentation-template");
fileExtensionMap.put("ods", "application/vnd.oasis.opendocument.spreadsheet");
fileExtensionMap.put("ots", "application/vnd.oasis.opendocument.spreadsheet-template");
fileExtensionMap.put("odc", "application/vnd.oasis.opendocument.chart");
fileExtensionMap.put("odf", "application/vnd.oasis.opendocument.formula");
fileExtensionMap.put("odb", "application/vnd.oasis.opendocument.database");
fileExtensionMap.put("odi", "application/vnd.oasis.opendocument.image");
fileExtensionMap.put("oxt", "application/vnd.openofficeorg.extension");
// Other
fileExtensionMap.put("txt", "text/plain");
fileExtensionMap.put("rtf", "application/rtf");
fileExtensionMap.put("pdf", "application/pdf");
}
Run Code Online (Sandbox Code Playgroud)
对我来说效果很好,希望对您有所帮助!
最可靠的方法是使用Files.probeContentType,但这需要一个实际的文件,部分原因是并非所有操作系统都依赖扩展名来确定文件类型。
\n\n在 Linux 中,下一个最佳方法是new MimetypesFileTypeMap("/etc/mime.types"),它将真正基于系统的映射。我不知道 OS X 是否有一个mime.types文件(尽管搜索显示CUPS for OS X 使用这样的文件,具有增强但主要向后兼容的语法)。
据我所知,Windows 中没有内置的 Java 类用于获取 MIME-type\xe2\x86\x94extension 映射。
\n\nURLConnection.getFileNameMap()返回一个具有相当数量条目的 FileNameMap,但仍然不基于系统的映射。例如,在我的 Linux 系统上,它为 .bz2 和 .rpm 文件返回 null。
FileTypeMap.getDefaultFileTypeMap()似乎有一些条目,但它显然也不是基于系统的映射。至少在我的系统上,它为 .png 文件返回“application/octet-stream”。
我认为最简单的事情是将它们全部封装在一个类中:
\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.net.FileNameMap;\nimport java.net.URLConnection;\nimport java.util.logging.Logger;\nimport java.util.logging.Level;\nimport javax.activation.FileTypeMap;\nimport javax.activation.MimetypesFileTypeMap;\n\npublic class MimeTypes {\n\n private static final Logger logger =\n Logger.getLogger(MimeTypes.class.getName());\n\n private static final String DEFAULT_TYPE = "application/octet-stream";\n\n private static final Path mimeTypesFile = Paths.get("/etc/mime.types");\n\n private final FileNameMap fileNameMap = URLConnection.getFileNameMap();\n\n private final FileTypeMap fileTypeMap = FileTypeMap.getDefaultFileTypeMap();\n\n private final FileTypeMap mimeTypesMap;\n\n public MimeTypes() {\n FileTypeMap map = null;\n if (Files.isRegularFile(mimeTypesFile)) {\n try {\n map = new MimetypesFileTypeMap(mimeTypesFile.toString());\n } catch (IOException e) {\n logger.log(Level.WARNING, "Couldn\'t read " + mimeTypesFile, e);\n }\n }\n mimeTypesMap = map;\n }\n\n public String getContentType(String filename) {\n String type = null;\n\n if (mimeTypesMap != null) {\n type = mimeTypesMap.getContentType(filename);\n }\n\n if (type == null || type.equals(DEFAULT_TYPE)) {\n type = fileNameMap.getContentTypeFor(filename);\n }\n\n if (type == null || type.equals(DEFAULT_TYPE)) {\n type = fileTypeMap.getContentType(filename);\n }\n\n return type;\n }\n\n public static void main(String[] args) {\n\n MimeTypes mimeTypes = new MimeTypes();\n\n for (String arg : args) {\n System.out.printf("Type of file \\"%s\\" is \\"%s\\"%n",\n arg, mimeTypes.getContentType(arg));\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这会给你带来相当好的结果。如果你想在 Windows 中进行真正的基于平台的 MIME 类型检查,我知道的唯一方法是读取注册表:
\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.net.FileNameMap;\nimport java.net.URLConnection;\nimport java.util.logging.Logger;\nimport java.util.logging.Level;\nimport javax.activation.FileTypeMap;\nimport javax.activation.MimetypesFileTypeMap;\n\nimport java.io.File;\nimport java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.InputStreamReader;\nimport java.io.OutputStreamWriter;\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Collections;\nimport java.util.Formatter;\n\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.ExecutionException;\n\npublic class MimeTypes {\n\n private static final Logger logger =\n Logger.getLogger(MimeTypes.class.getName());\n\n private static final String DEFAULT_TYPE = "application/octet-stream";\n\n private static final Path mimeTypesFile = Paths.get("/etc/mime.types");\n\n private final FileNameMap fileNameMap = URLConnection.getFileNameMap();\n\n private final FileTypeMap fileTypeMap = FileTypeMap.getDefaultFileTypeMap();\n\n private final FileTypeMap mimeTypesMap;\n\n public MimeTypes() {\n FileTypeMap map = null;\n\n if (Files.isRegularFile(mimeTypesFile)) {\n try {\n map = new MimetypesFileTypeMap(mimeTypesFile.toString());\n } catch (IOException e) {\n logger.log(Level.WARNING, "Couldn\'t read " + mimeTypesFile, e);\n }\n }\n\n if (map == null && System.getProperty("os.name").contains("Windows")) {\n try {\n map = new WindowsFileTypeMap();\n } catch (IOException e) {\n logger.log(Level.WARNING, "Couldn\'t read registered types", e);\n } catch (InterruptedException e) {\n logger.log(Level.INFO, "Interrupted; read canceled", e);\n }\n }\n\n mimeTypesMap = map;\n }\n\n public String getContentType(String filename) {\n String type = null;\n\n if (mimeTypesMap != null) {\n type = mimeTypesMap.getContentType(filename);\n }\n\n if (type == null || type.equals(DEFAULT_TYPE)) {\n type = fileNameMap.getContentTypeFor(filename);\n }\n\n if (type == null || type.equals(DEFAULT_TYPE)) {\n type = fileTypeMap.getContentType(filename);\n }\n\n return type;\n }\n\n private static class WindowsFileTypeMap\n extends FileTypeMap {\n\n private final Map<String, String> extensionToMimeType;\n\n public WindowsFileTypeMap()\n throws IOException,\n InterruptedException {\n\n ProcessBuilder builder =\n new ProcessBuilder("PowerShell.exe", "-Command", "-");\n\n Process process = builder.start();\n List<String> regEntryNames = getOutput(process, String.format(\n "Get-ChildItem \\"Registry::HKEY_CLASSES_ROOT\\\\\\" |"\n + " Select-String -InputObject { $_.Name }"\n + " -SimpleMatch -Pattern \\"HKEY_CLASSES_ROOT\\\\.\\"%n"));\n\n Formatter input = new Formatter();\n for (String name : regEntryNames) {\n input.format(\n "$values = Get-ItemProperty \\"Registry::%s\\"%n" +\n "$values.\\"Content Type\\" + \\" \\"%n", name);\n }\n\n process = builder.start();\n List<String> mimeTypes = getOutput(process, input.toString());\n\n int len = regEntryNames.size();\n extensionToMimeType = new HashMap<>(len);\n for (int i = 0; i < len; i++) {\n String mimeType = mimeTypes.get(i).trim();\n if (!mimeType.isEmpty()) {\n String extension =\n regEntryNames.get(i).replace("HKEY_CLASSES_ROOT\\\\", "");\n extensionToMimeType.put(extension, mimeType);\n }\n }\n }\n\n @Override\n public String getContentType(File file) {\n return getContentType(file.toString());\n }\n\n @Override\n public String getContentType(String filename) {\n int period = filename.lastIndexOf(\'.\');\n if (period < 0) {\n return DEFAULT_TYPE;\n }\n\n String ext = filename.substring(period);\n String type = extensionToMimeType.get(ext);\n return (type != null ? type : DEFAULT_TYPE);\n }\n\n private static List<String> getOutput(final Process process,\n final String input)\n throws IOException,\n InterruptedException {\n\n Callable<Void> inputSender = new Callable<Void>() {\n @Override\n public Void call()\n throws IOException {\n try (BufferedWriter writer =\n new BufferedWriter(\n new OutputStreamWriter(\n process.getOutputStream()))) {\n writer.write(input);\n }\n return null;\n }\n };\n\n ExecutorService executor = Executors.newSingleThreadExecutor();\n Future<?> inputSenderStatus = executor.submit(inputSender);\n\n List<String> lines;\n try (BufferedReader reader =\n new BufferedReader(\n new InputStreamReader(\n process.getInputStream()))) {\n lines = new ArrayList<>();\n String line;\n while ((line = reader.readLine()) != null) {\n lines.add(line);\n }\n }\n\n try {\n inputSenderStatus.get();\n } catch (ExecutionException e) {\n throw new IOException(e);\n }\n\n executor.shutdown();\n executor.awaitTermination(30, TimeUnit.SECONDS);\n\n process.waitFor();\n\n return lines;\n }\n }\n\n public static void main(String[] args) {\n\n MimeTypes mimeTypes = new MimeTypes();\n\n for (String arg : args) {\n System.out.printf("Type of file \\"%s\\" is \\"%s\\"%n",\n arg, mimeTypes.getContentType(arg));\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n