C# 在文件名(C)中不存在文件扩展名时从文件中检索文件扩展名?

C# 在文件名(C)中不存在文件扩展名时从文件中检索文件扩展名?,c#,.net,C#,.net,我试着搜索这个,但我的谷歌搜索失败了。我有一个满是文件的目录,这些文件只是它们的GUID: b3445ffb-55f4-4538-bc6f-13534fd549f6 我知道它们只能是少数几个文件扩展名doc、docx、pdf、jpg,但显然文件扩展名并不存在。我可以编写一个脚本,简单地尝试使用所有已知的文件扩展名打开文件,但这不是很有效。是否仍有方法读取文件并确定文件应该是什么 OSX在文件中存储文件类型代码,我希望Windows在文件中存储类似的元数据,而文件扩展名只是一个历史工件。我会这么

我试着搜索这个,但我的谷歌搜索失败了。我有一个满是文件的目录,这些文件只是它们的GUID:

b3445ffb-55f4-4538-bc6f-13534fd549f6
我知道它们只能是少数几个文件扩展名doc、docx、pdf、jpg,但显然文件扩展名并不存在。我可以编写一个脚本,简单地尝试使用所有已知的文件扩展名打开文件,但这不是很有效。是否仍有方法读取文件并确定文件应该是什么

OSX在文件中存储文件类型代码,我希望Windows在文件中存储类似的元数据,而文件扩展名只是一个历史工件。我会这么幸运吗


注意:由于您可能想知道为什么我有一个满是GUID的目录,因此假设数据库会跟踪GUID并将其与文件名和扩展名匹配,但该表已被删除。

否,Windows在文件系统中不提供此元数据。由于您只需要担心几种类型,因此以编程方式检查文件头并查看将文件重命名为哪个扩展名并不困难。

否,Windows在文件系统中不提供此元数据。因为您只需要担心几个类型,所以以编程方式检查文件头并查看将文件重命名为哪个扩展名并不困难。

我建议在记事本中打开文件并查找文件类型的一些指示符

例如:PDF以%PDF等开头

然后寻找这些指标,对图像进行某种消除或重命名为jpg anf try and open


另外,请尝试从备份中还原以获取更多线索。

我建议在记事本中打开文件,并查找文件类型的一些指示符

例如:PDF以%PDF等开头

然后寻找这些指标,对图像进行某种消除或重命名为jpg anf try and open


还可以尝试从备份中还原以获取更多线索。

要了解文件中的内容类型,您需要知道您要查找的内容的签名或幻码。有些扩展可能没有这个特性。您可以使用来创建一个识别某些扩展名的类。

要找出文件中的内容类型,您需要知道所查找内容的签名或幻数。有些扩展可能没有这个特性。您可以使用创建一个识别某些扩展名的类。

这些文件头应该位于该特定类型的每个有效文件上

JPEG

PDF

医生

DOCX

为了好玩,我用F写了一个与文件匹配的小应用程序。我喜欢模式匹配


这些文件头应该位于该特定类型的每个有效文件上

JPEG

PDF

医生

DOCX

为了好玩,我用F写了一个与文件匹配的小应用程序。我喜欢模式匹配


每个文件都有不同的格式,因此您可以深入研究它们,找出PDF文件相对于.doc的开头是什么样子。Docx是一种压缩格式,尽管我不确定它是否经过压缩,所以它将在其中的某个位置存储公共文件名。JPG可能非常具体


您正在谈论的文件有多少?

每个文件都有不同的格式,因此您可以深入了解它们,并找出PDF文件相对于.doc的开头是什么样子。Docx是一种压缩格式,尽管我不确定它是否经过压缩,所以它将在其中的某个位置存储公共文件名。JPG可能非常具体


你说的是多少文件?

如果只是一些文件类型,我会尝试使用自动化打开文件。 首先,将其加载为图片,如果失败,尝试将其加载到word对象中,如果失败,尝试将其加载到excel对象中,依此类推。修复最普通的文件扩展名docx、xls、pdf、jpg不需要超过20行代码

这里有一个VB的例子来说明我的意思。只需首先将对Microsoft.Office.Interop.Excel和Microsoft.Office.Interop.Word的引用添加到项目中即可。使用onlone-vb-c-converter将其转换为c或自己重写,这只是一个示例

Public Class Form1
    Private MyFolder As String = "C:\MyFolder\"
    Dim p As New PictureBox
    Dim w As New Microsoft.Office.Interop.Word.Application
    Dim x As New Microsoft.Office.Interop.Excel.Application

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        For Each file In IO.Directory.GetFiles(MyFolder)
            ProcessFile(file)
        Next
    End Sub

    Sub ProcessFile(ByVal FileName As String)
        If TryJpeg(FileName) Then Exit Sub
        If TryWordDoc(FileName) Then Exit Sub
        If TryExcelDoc(FileName) Then Exit Sub    
    End Sub

    Function TryJpeg(ByVal Filename As String) As Boolean

        Try
            p.Image = Image.FromFile(MyFolder & Filename)
            'it worked, so we assume it is a picture, rename it to jpg.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".jpg")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Function TryWordDoc(ByVal Filename As String) As Boolean

        Try
            w.Documents.Open(MyFolder & Filename)
            'it worked, so we assume it is a word document, rename it to docx.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".docx")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Function TryExcelDoc(ByVal Filename As String) As Boolean
        Try
            x.Workbooks.Open(MyFolder & Filename)
            'it worked, so we assume it is a excel document, rename it to xlsx.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".xlsx")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

End Class

如果只是一些文件类型,我会尝试使用自动化打开文件。 首先,将其加载为图片,如果失败,尝试将其加载到word对象中,如果失败,尝试将其加载到excel对象中,依此类推。修复最普通的文件扩展名docx、xls、pdf、jpg不需要超过20行代码

这里有一个VB的例子来说明我的意思。只需首先将对Microsoft.Office.Interop.Excel和Microsoft.Office.Interop.Word的引用添加到项目中即可。使用onlone-vb-c-converter将其转换为c或自己重写,这只是一个示例

Public Class Form1
    Private MyFolder As String = "C:\MyFolder\"
    Dim p As New PictureBox
    Dim w As New Microsoft.Office.Interop.Word.Application
    Dim x As New Microsoft.Office.Interop.Excel.Application

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        For Each file In IO.Directory.GetFiles(MyFolder)
            ProcessFile(file)
        Next
    End Sub

    Sub ProcessFile(ByVal FileName As String)
        If TryJpeg(FileName) Then Exit Sub
        If TryWordDoc(FileName) Then Exit Sub
        If TryExcelDoc(FileName) Then Exit Sub    
    End Sub

    Function TryJpeg(ByVal Filename As String) As Boolean

        Try
            p.Image = Image.FromFile(MyFolder & Filename)
            'it worked, so we assume it is a picture, rename it to jpg.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".jpg")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Function TryWordDoc(ByVal Filename As String) As Boolean

        Try
            w.Documents.Open(MyFolder & Filename)
            'it worked, so we assume it is a word document, rename it to docx.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".docx")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Function TryExcelDoc(ByVal Filename As String) As Boolean
        Try
            x.Workbooks.Open(MyFolder & Filename)
            'it worked, so we assume it is a excel document, rename it to xlsx.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".xlsx")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

End Class

如前所述,Windows仅依赖文件扩展名来确定文件的类型。但是你可以 读取每个文件的前几个字节,并查找每种类型的区别签名。从提供的中,您需要的是:

.PDF = 25 50 44 46 ("%PDF") .JPG = FF D8 FF .DOC = D0 CF 11 E0 A1 B1 1A E1 (same for .XLS, .PPT, etc) .DOCX = 50 4B 03 04 (same for .ZIP, .XLSX, .PPTX, .JAR, etc)
请注意,DOC文件的签名与Office 2007 Word、Excel、Powerpoint等之前的其他Office文件格式相同。还请注意,DOCX文件实际上是具有不同扩展名的ZIP文件,因此此签名与基于ZIP其他Office 2007/2010应用程序、Java JAR、,等等。

如前所述,Windows仅依赖文件扩展名来确定文件的类型。但是,您可以读取每个文件的前几个字节,并查找每种类型的区别签名。从提供的中,您需要的是:

.PDF = 25 50 44 46 ("%PDF") .JPG = FF D8 FF .DOC = D0 CF 11 E0 A1 B1 1A E1 (same for .XLS, .PPT, etc) .DOCX = 50 4B 03 04 (same for .ZIP, .XLSX, .PPTX, .JAR, etc)
请注意,DOC文件的签名与Office 2007 Word、Excel、Powerpoint等之前的其他Office文件格式相同。还请注意,DOCX文件实际上是具有不同扩展名的ZIP文件,因此此签名与基于ZIP其他Office 2007/2010应用程序、Java JAR、,等等。

那么为什么您不能保留文件扩展名呢?那么为什么您不能保留文件扩展名呢?请注意,这是任何文件的有效开始,但是在这里得到误报的几率非常低@回答得好。我不知道神奇的数字,这就是诀窍。太棒了,谢谢@肯德里克-要记住的好建议,但在这种情况下,我认为受控环境意味着你可以放松一点@卢卡斯-我想他们会用淘汰法,我太懒了。。。但为了完整起见,我更新了我的答案:请注意,这对于任何文件来说都是一个有效的开始,但是在这里得到误报的几率非常低@回答得好。我不知道神奇的数字,这就是诀窍。太棒了,谢谢@肯德里克-要记住的好建议,但在这种情况下,我认为受控环境意味着你可以放松一点@卢卡斯-我想他们会用淘汰法,我太懒了。。。但为了完整起见,我更新了我的答案:
module Program =

    let main () =

        let files = 
            seq {
                for path in System.IO.Directory.GetFiles(directory) do
                    use fs = System.IO.File.OpenRead(path)
                    let buffer = Array.zeroCreate 8
                    let read = fs.Read(buffer, 0, 8)
                    match buffer with
                    | [| 0xFFuy; 0xD8uy; _; _; _; _; _; _; |] -> 
                        yield (path, ".jpg")
                    | [| 0x25uy; 0x50uy; 0x44uy; 0x46uy; _; _; _; _; |] -> 
                        yield (path, ".pdf")
                    | [| 0x50uy; 0x4Buy; 0x03uy; 0x04uy; _; _; _; _; |] -> 
                        yield (path, ".docx")
                    | [| 0xD0uy; 0xCFuy; 0x11uy; 0xE0uy; 0xA1uy; 0xB1uy; 0x1Auy; 0xE1uy; |] -> 
                        yield (path, ".doc")
                    | _ -> 
                        yield (path, ".unk")
            }
            |> Seq.toArray

        System.Console.ReadKey true |> ignore

    main()
Public Class Form1
    Private MyFolder As String = "C:\MyFolder\"
    Dim p As New PictureBox
    Dim w As New Microsoft.Office.Interop.Word.Application
    Dim x As New Microsoft.Office.Interop.Excel.Application

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        For Each file In IO.Directory.GetFiles(MyFolder)
            ProcessFile(file)
        Next
    End Sub

    Sub ProcessFile(ByVal FileName As String)
        If TryJpeg(FileName) Then Exit Sub
        If TryWordDoc(FileName) Then Exit Sub
        If TryExcelDoc(FileName) Then Exit Sub    
    End Sub

    Function TryJpeg(ByVal Filename As String) As Boolean

        Try
            p.Image = Image.FromFile(MyFolder & Filename)
            'it worked, so we assume it is a picture, rename it to jpg.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".jpg")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Function TryWordDoc(ByVal Filename As String) As Boolean

        Try
            w.Documents.Open(MyFolder & Filename)
            'it worked, so we assume it is a word document, rename it to docx.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".docx")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Function TryExcelDoc(ByVal Filename As String) As Boolean
        Try
            x.Workbooks.Open(MyFolder & Filename)
            'it worked, so we assume it is a excel document, rename it to xlsx.
            FileSystem.Rename(MyFolder & Filename, MyFolder & Filename & ".xlsx")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

End Class
.PDF = 25 50 44 46 ("%PDF") .JPG = FF D8 FF .DOC = D0 CF 11 E0 A1 B1 1A E1 (same for .XLS, .PPT, etc) .DOCX = 50 4B 03 04 (same for .ZIP, .XLSX, .PPTX, .JAR, etc)