Anil Namde
Anil Namde

Reputation: 6618

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

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 xyz only (extension removed) in this can we still get the type/extension of the file using/reading files data/metadata.

Thanks all

Upvotes: 7

Views: 5582

Answers (5)

Sky Sanders
Sky Sanders

Reputation: 37104

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;
}

Upvotes: 15

Kurru
Kurru

Reputation: 14331

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.
}

Upvotes: 0

JohnFx
JohnFx

Reputation: 34907

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.

Upvotes: 0

Mark Byers
Mark Byers

Reputation: 838974

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.

Upvotes: 3

spender
spender

Reputation: 120508

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.

Upvotes: 2

Related Questions