如何从具有 mime 类型 octet-stream 的没有扩展名的文件中提取文件扩展名?

Posted

技术标签:

【中文标题】如何从具有 mime 类型 octet-stream 的没有扩展名的文件中提取文件扩展名?【英文标题】:How to extract file extension from file with no extension with mime type octet-stream? 【发布时间】:2015-10-03 07:09:23 【问题描述】:

我有大量文件,它们的原始文件名已被我数据库中的 id 替换。例如,曾经的名称 word_document.doc 现在是 12345。通过一个过程,我失去了原来的名字。

我现在正在尝试提供这些文件以供下载。该人应该能够下载该文件并使用它的原始应用程序查看它。这些文件都采用以下格式之一:

.txt(文本) .doc(word文档) .docx(word文档) .wpd(完美字) .pdf (PDF) .rtf(富文本) .sxw(明星办公室) .odt(开放式办公室)

我正在使用

$fhandle = finfo_open(FILEINFO_MIME);
$file_mime_type = finfo_file($fhandle, $filepath);

获取 mime 类型,然后将 mime 类型映射到扩展。

我遇到的问题是某些文件的 mime 类型为 octet-stream。我在网上阅读过,这种类型似乎是二进制文件的杂项类型。我不能轻易说出扩展需要什么。在某些情况下,当我将其设置为 .wpd 时它会起作用,而在某些情况下则不会。 .sxw也是如此。

【问题讨论】:

大声笑,想想你帖子中的主要短语 - “通过一个过程,我失去了原来的名字”。您已经在数据库中保存了一些信息,为什么不将文件名也保存在数据库中? 这对你有帮助吗? tika.apache.org @degr 我确实将文件名保存在数据库中,但允许用户“删除”他们的文件。 “删除”只是删除数据库中包含文件名等信息的行。作为网站的一部分,我们需要保留这些文件并让它们仍然可以访问,因为这些文件现在归他人所有。 @Caleb Doucet 您需要从数据库中删除带有行的文件。如果您需要保留文件,您也可以在数据库中保留行,只需添加一个名为 - 删除的“位”字段。 @degr 我知道解决方案是只保留数据库记录,但这需要大量返工。 (这是一个大系统)预算无法满足您的提议。 【参考方案1】:

Symfony2分三步完成

1) mime_content_type

$type = mime_content_type($path);

// remove charset (added as of php 5.3)
if (false !== $pos = strpos($type, ';')) 
    $type = substr($type, 0, $pos);


return $type;

2) 文件 -b --mime

ob_start();
passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($path)), $return);
if ($return > 0) 
    ob_end_clean();

    return;


$type = trim(ob_get_clean());
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) 
    // it's not a type, but an error message
    return;


return $match[1];

3) 信息

if (!$finfo = new \finfo(FILEINFO_MIME_TYPE, $path)) 
    return;


return $finfo->file($path);

获得 mime-type 后,您可以从预定义的映射中获取扩展名,例如来自 here 或 here

$map = array(
    'application/msword' => 'doc',
    'application/x-msword' => 'doc',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
    'application/pdf' => 'pdf',
    'application/x-pdf' => 'pdf',
    'application/rtf' => 'rtf',
    'text/rtf' => 'rtf',
    'application/vnd.sun.xml.writer' => 'sxw',
    'application/vnd.oasis.opendocument.text' => 'odt',
    'text/plain' => 'txt',
);

【讨论】:

这些是从文件路径获取 mime 类型的好方法,但我已经在检索 mime 类型。我需要知道如何将八位字节流 mime 类型解析为适当的扩展名。 嗯,我不认为有 100% 的方法来确定扩展,但是结合这 3 种方法应该会做得很好。有时 95% 的自动化总比没有好。其他 5% 可以手动处理。他们很有可能拥有相同的扩展名:)

以上是关于如何从具有 mime 类型 octet-stream 的没有扩展名的文件中提取文件扩展名?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 php 在文件上设置 mime 类型?

如何设置本地文件的 MIME 类型?

将音频从浏览器流式传输到具有特定 MIME 类型的 node.js 服务器

如何在java中发送具有不同内容类型的mime multipart restful请求

不支持视频格式或 MIME 类型。 IIS 确实具有正确的 MIME 类型。

如何从 Java 中的 MIME 类型确定适当的文件扩展名