如何检查IWorkbook对象是否可以从文件stream构build?

我使用NPOI库来读取xlsx和xls文件。

我有这个代码:

IWorkbook workBook = null; string fileExtension = Path.GetExtension(path); using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { if (fileExtension == ".xls") workBook = new HSSFWorkbook(fs); else if (fileExtension == ".xlsx") workBook = new XSSFWorkbook(fs); } 

而且它是完美的工作。 但是,excel文件的path并不总是以扩展名(.xls或.xlsx)为名。

所以我需要检查fs suitebale是否为HSSFWorkbook()XSSFWorkbook()

任何想法如何检查它没有扩展名的文件?

  IWorkbook workBook = null; string fileExtension = Path.GetExtension(path); using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { workBook = WorkbookFactory.Create(fs); } 

WorkbookFactory.Create()方法根据从xls或xlsx文件构build的fileStreem参数构造IWorkbook。

https://en.wikipedia.org/wiki/List_of_file_signatures应用文件头信息,我们可以使用这样的东西:

 public static class FormatRecognizer { public static Boolean IsZipFile(Stream stream) { if (stream == null) throw new ArgumentNullException(paramName: nameof(stream)); var zipHeader = new Byte[] { 0x50, 0x4B, 0x03, 0x04 }; var streamBytes = GetBytesAndRestore(stream, zipHeader.Length); return streamBytes.SequenceEqual(zipHeader); } public static Boolean IsOffice2003File(Stream stream) { if (stream == null) throw new ArgumentNullException(paramName: nameof(stream)); var officeHeader = new Byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, }; var streamBytes = GetBytesAndRestore(stream, officeHeader.Length); return streamBytes.SequenceEqual(officeHeader); } private static IEnumerable<Byte> GetBytesAndRestore(Stream stream, Int32 bytesCount) { if (stream == null) throw new ArgumentNullException(paramName: nameof(stream)); var position = stream.Position; try { using (var reader = new BinaryReader(stream, Encoding.Default, leaveOpen: true)) { return reader.ReadBytes(bytesCount); } } finally { stream.Position = position; } } } 

 private static void PrintFormatInfo(String path) { Console.WriteLine("File at '{0}'", path); using (var stream = File.Open(path, FileMode.Open)) { PrintFormatInfo(stream); } } private static void PrintFormatInfo(Stream stream) { Console.WriteLine("Is office 2003 = {0}", FormatRecognizer.IsOffice2003File(stream)); Console.WriteLine("Is zip file (possibly xlsx) = {0}", FormatRecognizer.IsZipFile(stream)); } 

 PrintFormatInfo("1.txt"); PrintFormatInfo("1.xls"); PrintFormatInfo("1.xlsx"); 

这不是绝对可靠的,因为IsZipFile将为简单的zip压缩文件返回true,并且IsOffice2003File也将会成功执行doc,ppt等。

但这是我能想到的最简单的解决scheme。 而任何更正确的将需要更深入的文件格式的知识,这可能会或可能不是你所需要的。