将内存流转换为数组,但只接受指定数量的元素

  • 本文关键字:元素 转换 内存 数组 c# arrays .net
  • 更新时间 :
  • 英文 :


我对实现图像格式验证感兴趣。我正在使用一个输入文件(如IFormFile),我想将其编码为字节,并将这些字节与jpeg和png等格式的起始字节进行比较。例如,如果文件的前两个字节等于jpeg的字节,则该文件为jpeg图像。

附带的实现将整个文件转换为字节数组,这似乎效率低下:

using var stream = new MemoryStream();
file.CopyTo(stream);
byte[] checkIfImage = stream.ToArray();

然后,我们将其与jpeg或png字节进行比较。

var png = new byte[] { 137, 80 };
var jpeg = new byte[] { 255, 216 };

与其创建这个包含文件所有字节的低效数组,我想创建一个只包含前两个字节的数组,这样比较将是有效的。然而,我不能简单地在.ToArray()之后加上.Take(2)或类似的东西。

我该怎么办?

谢谢!

直接使用流。读方法

var firstBytes = new byte[2];
var nrBytesRead = filestream.Read(firstBytes);
if(nrBytesRead == firstBytes.Length){
// do the comparison
}
像binaryreader这样的类可能也很有用。将整个流读入内存可能很方便,但如果考虑到性能或内存使用,通常应避免这样做。

不考虑你在概念上或其他方面遇到的任何问题…由于您正在MemoryStream分配,因此您不妨只使用GetBuffer来访问底层数组。从这里你可以使用任何你喜欢的比较技巧。

在这个例子中,我使用Memory<T>ReadOnlyMemory<T>,并使用SequenceEqual来检查模式(¯_(ツ)_/¯)

给定

private static readonly (string Name, ReadOnlyMemory<byte> Pattern)[] _patterns =
{
("png", new byte[] {1, 2}),
("jpj", new byte[] {1, 216}),
};

使用

using var file = new MemoryStream(new byte[] {1, 2, 3, 4, 5});
using var stream = new MemoryStream();
file.CopyTo(stream);
var mem = stream.GetBuffer().AsMemory();
foreach (var (name, pattern) in _patterns) 
if (pattern.Span.SequenceEqual(mem.Span(0,pattern.Span.Length)))
Console.WriteLine("Found : " + name + ", " + Convert.ToHexString(pattern.Span));

Found : png, 0102

<子>免责声明1如果你使用的是旧的、过时的。net框架,那么一切就都完了。您需要使用数组和蜡笔来完成此操作

<子>免责声明2这并不是世界上最伟大的代码,它只是一个致敬

最新更新