在我公司,我需要将mime类型与文件扩展名进行比较,原因更多。我有CommonsMultipartFile
。我试图找出做这种比较的最佳方法。我见过MimetypesFileTypeMap
,但不确定这是否可行。我试图避免(或限制)任何硬编码。
我得到了这样的值:
CommonsMultipartFile file = ...;
String fileName = file.getOriginalFilename();
String contentType = file.getContentType();
String extension = FilenameUtils.getExtension(fileName);
我感谢任何指导和帮助。谢谢!
答案 0 :(得分:4)
该案例的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;
}
第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");
}
对我来说很好,希望有所帮助!
答案 1 :(得分:4)
最可靠的方法是使用Files.probeContentType,但这需要一个实际的文件,部分原因是并非所有操作系统都依赖扩展来确定文件类型。
在Linux中,下一个最好的方法是new MimetypesFileTypeMap("/etc/mime.types")
,它将真正基于系统的映射。我不知道OS X是否有mime.types
文件(尽管搜索显示OS X的CUPS使用这样的文件,但增强但主要是向后兼容的语法)。
据我所知,没有内置的Java类可以在Windows中获取MIME-type↔extension映射。
URLConnection.getFileNameMap()
返回一个FileNameMap,它具有相当数量的条目,但仍然不基于系统的映射。例如,在我的Linux系统上,它为.bz2和.rpm文件返回null。
FileTypeMap.getDefaultFileTypeMap()
似乎有一些条目,但它显然也不是基于系统的映射。至少在我的系统上,它为.png文件返回“application / octet-stream”。
我认为最简单的方法是将所有这些内容封装在一个类中:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
public class MimeTypes {
private static final Logger logger =
Logger.getLogger(MimeTypes.class.getName());
private static final String DEFAULT_TYPE = "application/octet-stream";
private static final Path mimeTypesFile = Paths.get("/etc/mime.types");
private final FileNameMap fileNameMap = URLConnection.getFileNameMap();
private final FileTypeMap fileTypeMap = FileTypeMap.getDefaultFileTypeMap();
private final FileTypeMap mimeTypesMap;
public MimeTypes() {
FileTypeMap map = null;
if (Files.isRegularFile(mimeTypesFile)) {
try {
map = new MimetypesFileTypeMap(mimeTypesFile.toString());
} catch (IOException e) {
logger.log(Level.WARNING, "Couldn't read " + mimeTypesFile, e);
}
}
mimeTypesMap = map;
}
public String getContentType(String filename) {
String type = null;
if (mimeTypesMap != null) {
type = mimeTypesMap.getContentType(filename);
}
if (type == null || type.equals(DEFAULT_TYPE)) {
type = fileNameMap.getContentTypeFor(filename);
}
if (type == null || type.equals(DEFAULT_TYPE)) {
type = fileTypeMap.getContentType(filename);
}
return type;
}
public static void main(String[] args) {
MimeTypes mimeTypes = new MimeTypes();
for (String arg : args) {
System.out.printf("Type of file \"%s\" is \"%s\"%n",
arg, mimeTypes.getContentType(arg));
}
}
}
这将为您带来相当不错的结果。如果你想在Windows中进行真正的基于平台的MIME类型检查,我知道这样做的唯一方法是阅读注册表:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Collections;
import java.util.Formatter;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
public class MimeTypes {
private static final Logger logger =
Logger.getLogger(MimeTypes.class.getName());
private static final String DEFAULT_TYPE = "application/octet-stream";
private static final Path mimeTypesFile = Paths.get("/etc/mime.types");
private final FileNameMap fileNameMap = URLConnection.getFileNameMap();
private final FileTypeMap fileTypeMap = FileTypeMap.getDefaultFileTypeMap();
private final FileTypeMap mimeTypesMap;
public MimeTypes() {
FileTypeMap map = null;
if (Files.isRegularFile(mimeTypesFile)) {
try {
map = new MimetypesFileTypeMap(mimeTypesFile.toString());
} catch (IOException e) {
logger.log(Level.WARNING, "Couldn't read " + mimeTypesFile, e);
}
}
if (map == null && System.getProperty("os.name").contains("Windows")) {
try {
map = new WindowsFileTypeMap();
} catch (IOException e) {
logger.log(Level.WARNING, "Couldn't read registered types", e);
} catch (InterruptedException e) {
logger.log(Level.INFO, "Interrupted; read canceled", e);
}
}
mimeTypesMap = map;
}
public String getContentType(String filename) {
String type = null;
if (mimeTypesMap != null) {
type = mimeTypesMap.getContentType(filename);
}
if (type == null || type.equals(DEFAULT_TYPE)) {
type = fileNameMap.getContentTypeFor(filename);
}
if (type == null || type.equals(DEFAULT_TYPE)) {
type = fileTypeMap.getContentType(filename);
}
return type;
}
private static class WindowsFileTypeMap
extends FileTypeMap {
private final Map<String, String> extensionToMimeType;
public WindowsFileTypeMap()
throws IOException,
InterruptedException {
ProcessBuilder builder =
new ProcessBuilder("PowerShell.exe", "-Command", "-");
Process process = builder.start();
List<String> regEntryNames = getOutput(process, String.format(
"Get-ChildItem \"Registry::HKEY_CLASSES_ROOT\\\" |"
+ " Select-String -InputObject { $_.Name }"
+ " -SimpleMatch -Pattern \"HKEY_CLASSES_ROOT\\.\"%n"));
Formatter input = new Formatter();
for (String name : regEntryNames) {
input.format(
"$values = Get-ItemProperty \"Registry::%s\"%n" +
"$values.\"Content Type\" + \" \"%n", name);
}
process = builder.start();
List<String> mimeTypes = getOutput(process, input.toString());
int len = regEntryNames.size();
extensionToMimeType = new HashMap<>(len);
for (int i = 0; i < len; i++) {
String mimeType = mimeTypes.get(i).trim();
if (!mimeType.isEmpty()) {
String extension =
regEntryNames.get(i).replace("HKEY_CLASSES_ROOT\\", "");
extensionToMimeType.put(extension, mimeType);
}
}
}
@Override
public String getContentType(File file) {
return getContentType(file.toString());
}
@Override
public String getContentType(String filename) {
int period = filename.lastIndexOf('.');
if (period < 0) {
return DEFAULT_TYPE;
}
String ext = filename.substring(period);
String type = extensionToMimeType.get(ext);
return (type != null ? type : DEFAULT_TYPE);
}
private static List<String> getOutput(final Process process,
final String input)
throws IOException,
InterruptedException {
Callable<Void> inputSender = new Callable<Void>() {
@Override
public Void call()
throws IOException {
try (BufferedWriter writer =
new BufferedWriter(
new OutputStreamWriter(
process.getOutputStream()))) {
writer.write(input);
}
return null;
}
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> inputSenderStatus = executor.submit(inputSender);
List<String> lines;
try (BufferedReader reader =
new BufferedReader(
new InputStreamReader(
process.getInputStream()))) {
lines = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
}
try {
inputSenderStatus.get();
} catch (ExecutionException e) {
throw new IOException(e);
}
executor.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS);
process.waitFor();
return lines;
}
}
public static void main(String[] args) {
MimeTypes mimeTypes = new MimeTypes();
for (String arg : args) {
System.out.printf("Type of file \"%s\" is \"%s\"%n",
arg, mimeTypes.getContentType(arg));
}
}
}
答案 2 :(得分:3)
我有一个课程https://github.com/nablex/utils-io/blob/master/src/main/java/be/nabu/utils/io/ContentTypeMap.java可以做到这一点。
它添加了一些在URLConnection中缺少的东西:
此外,可以使用以下方法将其插入URLConnection:
ContentTypeMap.register()
默认情况下,它使用文件加载映射:https://github.com/nablex/utils-io/blob/master/src/main/resources/mime.properties
答案 3 :(得分:0)
boolean getMimeType(String fileName) {
boolean flag=false;
Map<String, String> fileExtnMap= new HashMap<String, String>();
fileExtnMap.put("jpg","image/jpg");
fileExtnMap.put("jpeg","image/jpeg");
fileExtnMap.put("pdf","application/pdf");
FileNameMap fileMap = URLConnection.getFileNameMap();
String contentType=fileMap .getContentTypeFor(fileName);
String[] extn= fileName.split("\\.");
contentType = fileExtnMap.get(extn[1]);
if(extn[1].equals("pdf") && contentType.equals("application/pdf") || extn[1].equals("jpg") && contentType.equals("image/jpg") || extn[1].equals("jpeg") && contentType.equals("image/jpeg")){
flag=true;
}
return flag;
}