문제

메모리에 바이트 배열이 있고 파일에서 읽습니다.새 바이트 배열을 생성하고 한 번에 각 바이트를 복사하지 않고도 특정 지점(인덱스)에서 바이트 배열을 분할하여 메모리 내 작업 공간을 늘리고 싶습니다.내가 원하는 것은 다음과 같습니다.

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<T> : IEnumerable<T>
{
    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<T> GetEnumerator()
    {
        for (int i = offset; i < offset + count; i++)
            yield return array[i];
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        IEnumerator<T> 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<byte> p1 = new ArrayView<byte>(arr, 0, 5);
        ArrayView<byte> p2 = new ArrayView<byte>(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();
    }
}

다른 팁

참고하세요. System.ArraySegment<T> 구조는 기본적으로 똑같습니다 ArrayView<T> 위의 코드에서.원하는 경우 동일한 방식으로 기본 구조를 사용할 수 있습니다.

Linq를 사용하는 C#에서는 다음을 수행할 수 있습니다.

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

;)

이거 한번 해봐:

private IEnumerable<byte[]> 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<T>.확장 방법 및 사용 예는 다음과 같습니다.

public static class ArrayExtensionMethods
{
    public static ArraySegment<T> GetSegment<T>(this T[] arr, int offset, int? count = null)
    {
        if (count == null) { count = arr.Length - offset; }
        return new ArraySegment<T>(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);
    }
}

당신은 할 수 없습니다.원하는 것은 시작점과 항목 수를 유지하는 것입니다.본질적으로 반복자를 빌드합니다.이것이 C++이라면 그냥 사용할 수 있습니다 std::vector<int> 내장된 것을 사용하세요.

C#에서는 시작 인덱스, 개수 및 구현을 보유하는 작은 반복자 클래스를 구축했습니다. IEnumerable<>.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top