文件类型 - 获取原始扩展名

5
如何在文件被重命名后找到文件扩展名?是否有任何工具可用于此?
例如:我有一个文件“1.doc”,我希望每个人都知道这是一个Word文档,我只是将其重命名为“1.txt”。但实际上该文件是一个Word文档;如何获取原始文件扩展名?

“名字有什么重要性。” 扩展名只是一个名称,与实际文件内容的类型没有太大关系。 - user562374
另一个适合 “混淆思路” 标签 的候选人 - 名字有什么关系呢? - user395760
@delnan:并不完全正确。不同的文件格式确实有一些特征标志,通过这些标志可以识别出文件的类型(比如PNG或GIF格式)。另一方面,Windows过去(现在还是不确定)仅仅通过文件扩展名来识别文件类型-所以如果你重命名文件,Windows就不知道该如何处理它。 - Piskvor left the building
好的,有一个文件例如1.fgf,有人把它重命名为“fgf”,我该如何使用该文件?该文件可能是Word文档、mp3等等... - Thiru G
3个回答

4

当然可以 :)

这是C#代码,你可以构建自己的工具 ;)

using System.Runtime.InteropServices;
using System.IO;
using Microsoft.Win32;

    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
    private extern static System.UInt32 FindMimeFromData(
        System.UInt32 pBC,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
        [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
        System.UInt32 cbSize,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
        System.UInt32 dwMimeFlags,
        out System.UInt32 ppwzMimeOut,
        System.UInt32 dwReserverd
    );


    public static string getMimeFromFile(string filename)
    {
        if (!File.Exists(filename))
            throw new FileNotFoundException(filename + " not found");

        byte[] buffer = new byte[256];
        using (FileStream fs = new FileStream(filename, FileMode.Open))
        {
            if (fs.Length >= 256)
                fs.Read(buffer, 0, 256);
            else
                fs.Read(buffer, 0, (int)fs.Length);
        }
        try
        {
            System.UInt32 mimetype;
            FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
            System.IntPtr mimeTypePtr = new IntPtr(mimetype);
            string mime = Marshal.PtrToStringUni(mimeTypePtr);
            Marshal.FreeCoTaskMem(mimeTypePtr);
            return mime;
        }
        catch (Exception e)
        {
            return "unknown/unknown";
        }
    }

你可以使用以下代码获取MIME类型。如果想从MIME类型中查找扩展名,只需进行一些谷歌搜索即可。

谢谢你,honibis。提取MIME类型不是问题 :-) - Thiru G
虽然这样做可以起作用,但你得到的不是原始扩展名,而是最好的猜测它可能是什么。请注意,这对某些类型的文件(例如ZIP归档文件,其“头”在文件末尾;因此,文件开头可以包含任何内容)可能无法正常工作。 - Piskvor left the building
对于zip文件,它返回:application/x-zip-compressed,实际上这不仅仅是猜测,因为原始文件扩展名严格与MIME类型相关联。 - honibis
@honibis:这只是一种基于格式特征和统计数据的有根据的猜测,大多数情况下都是正确的,但仍然是一种猜测。有些文件类型可能有多个扩展名:“它是image.jpg还是image.jpeg?”就像我说的,你的代码会起作用,可能有90%以上的准确率。只要知道FindMimeFromData是基于模式识别和统计数据运行的,而不是魔法 :) - Piskvor left the building
@Piskvor,有一种叫做“文件头”的东西,所有标准格式都有头部。前256个字节是头部所在的位置。因此,没有模式识别或魔法。 - honibis
1
@honibis:我有一种感觉,我们非常一致 :D - Piskvor left the building

3

不可能。如果您正在使用*nix类型的系统,请使用file命令确定文件格式。

如果您真的对这种事情(并且混乱您的工作流程)感到非常担心,可以采取两个措施:

  1. 对文件进行哈希,例如MD5哈希,以便您知道文件没有被篡改
  2. 注意文件的时间戳,以便您可以看到上次更改的时间
  3. 在该时间戳时注意文件的扩展名

这将在以下几个方面保护您:

哈希将确保您的文件未被更改。

时间戳将告诉您上次修改的时间。

扩展名将告诉您其原始扩展名。

由于只重命名文件扩展名不会修改其时间戳,因此需要第3步。

使用此类技术将在99.99999999999%的情况下告诉您,文件已被某些人或某些东西修改。


1
+1 - file 在大多数情况下非常擅长“猜测”原始格式。请注意,“猜测”一词的强调。 - Piskvor left the building

1

不行。你需要使用像 file 这样的工具来尝试检测文件的格式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接