Массив байтов в массив int16 - PullRequest
2 голосов
/ 26 марта 2012

Есть ли более эффективный способ преобразования байтового массива в массив int16? или есть способ использовать Buffer.BlockCopy для копирования двух байтов в массив int16 ???

public static int[] BYTarrToINT16arr(string fileName)
{
try
{
int bYte = 2;
byte[] buf = File.ReadAllBytes(fileName); 
int bufPos = 0;
int[] data = new int[buf.Length/2];
byte[] bt = new byte[bYte];
for (int i = 0; i < buf.Length/2; i++)
{
Array.Copy(buf, bufPos, bt, 0, bYte);
bufPos += bYte;
Array.Reverse(bt);
data[i] = BitConverter.ToInt16(bt, 0);
}
return data;
}
catch
{
return null;
}
}   

Ответы [ 5 ]

4 голосов
/ 26 марта 2012

Используйте FileStream и BinaryReader. Примерно так:

var int16List = List<Int16>();
using (var stream = new FileStream(filename, FileMode.Open))
using (var reader = new BinaryReader(stream))
{
    try
    {
        while (true)
            int16List.Add(reader.ReadInt16());
    }
    catch (EndOfStreamException ex)
    {
        // We've read the whole file
    }
}
return int16List.ToArray();

Вы также можете прочитать весь файл в byte[], а затем использовать MemoryStream вместо FileStream, если хотите.

Если вы сделаете это, вы также сможете заранее определить размер List и сделать его немного более эффективным.

1 голос
/ 28 мая 2012

Это работает, если вы не возражаете против использования межсервисных услуг. Я предполагаю, что это быстрее, чем другие методы.

using System.Runtime.InteropServices;   

public Int16[] Copy_Byte_Buffer_To_Int16_Buffer(byte[] buffer)

{
    Int16[] result = new Int16[1];
    int size = buffer.Length;
    if ((size % 2) != 0)
    {
        /* Error here */
        return result;
    }
    else
    {
        result = new Int16[size/2];
        IntPtr ptr_src = Marshal.AllocHGlobal (size);
        Marshal.Copy (buffer, 0, ptr_src, size);
        Marshal.Copy (ptr_src, result, 0, result.Length);
        Marshal.FreeHGlobal (ptr_src);
        return result;
    }
}
1 голос
/ 26 марта 2012

Помимо наличия возможности отключения по одному, если число байтов нечетное (вы пропустите последний байт), ваш код в порядке.Вы можете оптимизировать его, полностью удалив массив bt, поменяв местами байты i*2 и i*2+1 перед вызовом BitConverter.ToInt16 и передав i*2 в качестве начального индекса методу BitConverter.ToInt16.

0 голосов
/ 26 марта 2012
var bytes = File.ReadAllBytes(path);

var ints = bytes.TakeWhile((b, i) => i % 2 == 0).Select((b, i) => BitConverter.ToInt16(bytes, i));

if (bytes.Length % 2 == 1)
{
    ints = ints.Union(new[] {BitConverter.ToInt16(new byte[] {bytes[bytes.Length - 1], 0}, 0)});
}

return ints.ToArray();
0 голосов
/ 26 марта 2012

попробуй ...

int index = 0;            
var my16s = bytes.GroupBy(x => (index++) / 2)
           .Select(x => BitConverter.ToInt16(x.Reverse().ToArray(),0)).ToList();
...