我正在尝试将图像的字节“分块”。这将允许我分部分上传大图像。我将图像当前存储为一个大字节 []。我想将字节数组拆分为byte[]
最大长度为 512 个元素的 's。但是,我不确定如何以最有效的方式做到这一点。
有谁知道我怎样才能以最有效的方式做到这一点?
我为此编写了一个扩展,最初用于字符串,但决定使其通用。
public static T[] CopySlice<T>(this T[] source, int index, int length, bool padToLength = false)
{
int n = length;
T[] slice = null;
if (source.Length < index + length)
{
n = source.Length - index;
if (padToLength)
{
slice = new T[length];
}
}
if(slice == null) slice = new T[n];
Array.Copy(source, index, slice, 0, n);
return slice;
}
public static IEnumerable<T[]> Slices<T>(this T[] source, int count, bool padToLength = false)
{
for (var i = 0; i < source.Length; i += count)
yield return source.CopySlice(i, count, padToLength);
}
基本上,您可以像这样使用它:
byte[] myBytes; // original byte array
foreach(byte[] copySlice in myBytes.Slices(10))
{
// do something with each slice
}
编辑:我还在此处使用 Buffer.BlockCopy 提供了关于 SO 的答案,但 BlockCopy 仅适用于byte[]
数组,因此无法使用字符串的通用版本。
最有效的方法是:不要。如果您已经将图像作为单个字节 [],那么对于本地代码,只需指定偏移量和长度(可能是 som ArraySegment-of-byte)通常就足够了。如果您的上传 API 只使用 byte[],那么您仍然不应该将其完全分块;只需使用单个 512 缓冲区并使用 Buffer.BlockCopy 加载它将连续的数据片段。您可能需要调整 (Array.Resize)最终块的大小,但最多需要 2 个数组。
更好;首先避免需要 byte[]:考虑通过流 API 加载数据(如果数据来自文件,这将很好地工作);只需使用读取(在循环中,处理返回值等)来填充最大 512 的块。例如(未经测试,仅用于说明):
byte[] buffer = new byte[512];
while(true) {
int space = 512, read, offset = 0;
while(space > 0 && (read = stream.Read(buffer, offset, space)) > 0) {
space -= read;
offset += read;
}
// either a full buffer, or EOF
if(space != 0) { // EOF - final
if(offset != 0) { // something to send
Array.Resize(red buffer, offset);
Upload(buffer);
}
break;
} else { // full buffer
Upload(buffer);
}
}
public static IEnumerable<byte[]> Split(this byte[] value,int bufferLength){
int countOfArray = value.Length / bufferLength;
if(value.Length % bufferLength > 0)
countOfArray ++;
for(int i=0;i<countOfArray;i++)
{
yield return value.Skip(i * bufferLength).Take(bufferLength).ToArray();
}
}
这是我使用的扩展
我知道这很旧,但需要相同的解决方案,并且以下对我来说非常有效,希望这对某人有所帮助
private byte[][] ByteArrayToChunks(byte[] byteData, long BufferSize)
{
byte[][] chunks = byteData.Select((value, index) => new { PairNum = Math.Floor(index / (double)BufferSize), value }).GroupBy(pair => pair.PairNum).Select(grp => grp.Select(g => g.value).ToArray()).ToArray();
return chunks;
}