how to identify the extension/type of the file using C#?

前端 未结 5 2004
迷失自我
迷失自我 2021-01-03 00:55

i have a workflow where user is allowed to upload any file and then that file will be read.

Now my question is if user have image file xyz.jpg and he renamed it to

相关标签:
5条回答
  • 2021-01-03 01:12

    Are there specific file formats you need to detect? It makes the task a lot easier if you can narrow it down to a few formats that can be identified by the contents of the file.

    If you need to detect a broad range of file types, there are third party toolkits you can use, but I'll warn you that they tend to be very expensive. The two I am familiar with are Stellent's (now Oracle's) Outside In, and Autonomy Keyview. Both provide programmer toolkits.

    0 讨论(0)
  • 2021-01-03 01:14

    See PInvoke.net for more detail

       [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
        static extern int FindMimeFromData(IntPtr pBC,
              [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
             [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] 
            byte[] pBuffer,
              int cbSize,
                 [MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed,
              int dwMimeFlags,
              out IntPtr ppwzMimeOut,
              int dwReserved);
    

    Sample usage:

      public string MimeTypeFrom(byte[] dataBytes, string mimeProposed) {
       if (dataBytes == null)
         throw new ArgumentNullException("dataBytes");
       string mimeRet = String.Empty;
       IntPtr suggestPtr = IntPtr.Zero, filePtr = IntPtr.Zero, outPtr = IntPtr.Zero;
       if (mimeProposed != null && mimeProposed.Length > 0) {
         //suggestPtr = Marshal.StringToCoTaskMemUni(mimeProposed); // for your experiments ;-)
         mimeRet = mimeProposed;
       }
       int ret = FindMimeFromData(IntPtr.Zero, null, dataBytes, dataBytes.Length, mimeProposed, 0, out outPtr, 0);
       if (ret == 0 && outPtr != IntPtr.Zero) {
        //todo: this leaks memory outPtr must be freed
         return Marshal.PtrToStringUni(outPtr);
       }
       return mimeRet;
    }
    
    // call it this way:
    Trace.Write("MimeType is " + MimeTypeFrom(Encoding.ASCII.GetBytes("%PDF-"), "text/plain"));
    

    Another example:

    /// <summary>
    /// Ensures that file exists and retrieves the content type 
    /// </summary>
    /// <param name="file"></param>
    /// <returns>Returns for instance "images/jpeg" </returns>
    public static string getMimeFromFile(string file)
    {
        IntPtr mimeout;
        if (!System.IO.File.Exists(file))
        throw new FileNotFoundException(file + " not found");
    
        int MaxContent = (int)new FileInfo(file).Length;
        if (MaxContent > 4096) MaxContent = 4096;
        FileStream fs = File.OpenRead(file);
    
    
        byte[] buf = new byte[MaxContent];        
        fs.Read(buf, 0, MaxContent);
        fs.Close();
        int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out mimeout, 0);
    
        if (result != 0)
        throw Marshal.GetExceptionForHR(result);
        string mime = Marshal.PtrToStringUni(mimeout);
        Marshal.FreeCoTaskMem(mimeout);
        return mime;
    }
    
    0 讨论(0)
  • 2021-01-03 01:14

    You can use the unmanaged function FindMimeFromData in urlmon.dll.

    using System.Runtime.InteropServices;
    
    [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
    );
    

    See here for an example usage.

    0 讨论(0)
  • 2021-01-03 01:25

    If you just need to see if the uploaded file is an Image, just parse it accordingly

    try
    {
    Image image = Bitmap.FromStream(fileData);
    }
    catch(Exception e)
    {
        // this isn't an image.
    }
    
    0 讨论(0)
  • 2021-01-03 01:37

    Yes, probably for many file types this is possible, but it would require parsing of the binary contents of the file on a case by case basis.

    0 讨论(0)
提交回复
热议问题