Intereting Posts
Асинхронная обработка данных FromBluetoothAddressAsync никогда не возвращается в Windows 10 Creators Update в приложении WPF Проверить идентификатор пользователя в Active Directory с помощью C # Второй выбранный элемент выпадающего списка не изменяется в ASP.NET MVC C # и F # casting – в частности, ключевое слово ‘as’ C # – передача аргументов с пространством между ними в процесс Каков самый быстрый способ загрузки XML в XDocument? Можно ли получить динамические столбцы в wpf datagrid в шаблоне mvvm? Удаление повторяющихся элементов из списка, содержащего class с элементами массива Как отображать записи базы данных в представлении asp.net mvc «Вызов конструктора по типу« TestWPF.MainWindow », который соответствует указанным ограничениям привязки, сделал исключение». – Как это исправить? Отображение объектов с помощью LINQ и SubSonic Как выполнить модульное тестирование действия controllerа MVC, которое зависит от аутентификации в c #? Перекрестное drag and drop настраиваемого типа объекта в WinForms C # ASP.NET Resourcemanager для чтения локального .resx

Как разбить массив байтов

У меня есть массив байтов в памяти, считанный из файла. Я хотел бы разбить массив байтов в определенной точке (индексе), не создавая новый массив байтов и не копируя каждый байт за один раз, увеличивая длину записи в памяти операции. Я бы хотел что-то вроде этого:

byte[] largeBytes = [1,2,3,4,5,6,7,8,9]; byte[] smallPortion; smallPortion = split(largeBytes, 3); 

smallPortion равнялся 1,2,3,4
largeBytes будет равняться 5,6,7,8,9

Вот как я это сделал:

 using System; using System.Collections; using System.Collections.Generic; class ArrayView : IEnumerable { private readonly T[] array; private readonly int offset, count; public ArrayView(T[] array, int offset, int count) { this.array = array; this.offset = offset; this.count = count; } public int Length { get { return count; } } public T this[int index] { get { if (index < 0 || index >= this.count) throw new IndexOutOfRangeException(); else return this.array[offset + index]; } set { if (index < 0 || index >= this.count) throw new IndexOutOfRangeException(); else this.array[offset + index] = value; } } public IEnumerator GetEnumerator() { for (int i = offset; i < offset + count; i++) yield return array[i]; } IEnumerator IEnumerable.GetEnumerator() { IEnumerator enumerator = this.GetEnumerator(); while (enumerator.MoveNext()) { yield return enumerator.Current; } } } class Program { static void Main(string[] args) { byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; ArrayView p1 = new ArrayView(arr, 0, 5); ArrayView p2 = new ArrayView(arr, 5, 5); Console.WriteLine("First array:"); foreach (byte b in p1) { Console.Write(b); } Console.Write("\n"); Console.WriteLine("Second array:"); foreach (byte b in p2) { Console.Write(b); } Console.ReadKey(); } } 

FYI. Структура System.ArraySegment основном является тем же, что и ArrayView в приведенном выше коде. Вы можете использовать эту готовую структуру так же, если хотите.

В C # с Linq вы можете сделать это:

 smallPortion = largeBytes.Take(4).ToArray(); largeBytes = largeBytes.Skip(4).Take(5).ToArray(); 

😉

Попробуй это:

 private IEnumerable ArraySplit(byte[] bArray, int intBufforLengt) { int bArrayLenght = bArray.Length; byte[] bReturn = null; int i = 0; for (; bArrayLenght > (i + 1) * intBufforLengt; i++) { bReturn = new byte[intBufforLengt]; Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt); yield return bReturn; } int intBufforLeft = bArrayLenght - i * intBufforLengt; if (intBufforLeft > 0) { bReturn = new byte[intBufforLeft]; Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft); yield return bReturn; } } 

Я не уверен, что вы имеете в виду:

Я хотел бы разбить массив байтов в определенной точке (индексе), не создавая новый массив байтов и не копируя каждый байт за один раз, увеличивая длину записи в памяти операции.

На большинстве языков, конечно же, C #, как только массив был выделен, нет способа изменить его размер. Похоже, вы ищете способ изменить длину массива, чего вы не можете. Вы также хотите как-то переработать память для второй части массива, чтобы создать второй массив, который вы также не можете сделать.

В итоге: просто создайте новый массив.

Как сказал Эрен , вы можете использовать ArraySegment . Вот пример расширения и пример использования:

 public static class ArrayExtensionMethods { public static ArraySegment GetSegment(this T[] arr, int offset, int? count = null) { if (count == null) { count = arr.Length - offset; } return new ArraySegment(arr, offset, count.Value); } } void Main() { byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; var p1 = arr.GetSegment(0, 5); var p2 = arr.GetSegment(5); Console.WriteLine("First array:"); foreach (byte b in p1) { Console.Write(b); } Console.Write("\n"); Console.WriteLine("Second array:"); foreach (byte b in p2) { Console.Write(b); } } 

Вы не можете. Вы можете захотеть сохранить начальную точку и количество элементов; по сути, строить iteratorы. Если это C ++, вы можете просто использовать std::vector и использовать встроенные.

В C # я бы построил небольшой class iteratorа, который содержит индекс начала, подсчитывает и реализует IEnumerable<> .