문제

이 질문은 이미 여기에 답이 있습니다.

변환하는 간단한 방법이나 방법이 있습니까? Stream a byte[] C#에서?

도움이 되었습니까?

해결책

다음 기능을 호출하십시오

byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);

기능:

public static byte[] ReadToEnd(System.IO.Stream stream)
    {
        long originalPosition = 0;

        if(stream.CanSeek)
        {
             originalPosition = stream.Position;
             stream.Position = 0;
        }

        try
        {
            byte[] readBuffer = new byte[4096];

            int totalBytesRead = 0;
            int bytesRead;

            while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
            {
                totalBytesRead += bytesRead;

                if (totalBytesRead == readBuffer.Length)
                {
                    int nextByte = stream.ReadByte();
                    if (nextByte != -1)
                    {
                        byte[] temp = new byte[readBuffer.Length * 2];
                        Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                        Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                        readBuffer = temp;
                        totalBytesRead++;
                    }
                }
            }

            byte[] buffer = readBuffer;
            if (readBuffer.Length != totalBytesRead)
            {
                buffer = new byte[totalBytesRead];
                Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
            }
            return buffer;
        }
        finally
        {
            if(stream.CanSeek)
            {
                 stream.Position = originalPosition; 
            }
        }
    }

다른 팁

내가 아는 가장 짧은 솔루션 :

using(var memoryStream = new MemoryStream())
{
  sourceStream.CopyTo(memoryStream);
  return memoryStream.ToArray();
}

.NET 프레임 워크 4 이상에서 Stream 클래스는 내장되어 있습니다 CopyTo 사용할 수있는 방법.

이전 버전의 프레임 워크의 경우 편리한 도우미 기능은 다음과 같습니다.

public static void CopyStream(Stream input, Stream output)
{
    byte[] b = new byte[32768];
    int r;
    while ((r = input.Read(b, 0, b.Length)) > 0)
        output.Write(b, 0, r);
}

그런 다음 위의 방법 중 하나를 사용하여 복사하십시오. MemoryStream 그리고 전화 GetBuffer 그 위에:

var file = new FileStream("c:\\foo.txt", FileMode.Open);

var mem = new MemoryStream();

// If using .NET 4 or later:
file.CopyTo(mem);

// Otherwise:
CopyStream(file, mem);

// getting the internal buffer (no additional copying)
byte[] buffer = mem.GetBuffer();
long length = mem.Length; // the actual length of the data 
                          // (the array may be longer)

// if you need the array to be exactly as long as the data
byte[] truncated = mem.ToArray(); // makes another copy

편집하다: 원래 나는 Jason의 답변을 사용하는 것을 제안했습니다 Stream 그것은 Length 재산. 그러나 그것은 Stream 모든 내용을 단일로 반환합니다 Read, 반드시 사실은 아닙니다 ( Socket, 예를 들어.) 나는 Stream 지원하는 BCL의 구현 Length 그러나 요청보다 짧은 청크로 데이터를 반환 할 수 있지만 누구나 상속받을 수 있습니다. Stream 이것은 쉽게 그럴 수 있습니다.

대부분의 경우 위의 일반 솔루션을 사용하는 것이 더 간단하지만 아마도 배열로 직접 읽고 싶다고 가정합니다. bigEnough:

byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
    offset += r;

즉, 반복적으로 전화합니다 Read 데이터를 저장할 위치를 이동하십시오.

    byte[] buf;  // byte array
    Stream stream=Page.Request.InputStream;  //initialise new stream
    buf = new byte[stream.Length];  //declare arraysize
    stream.Read(buf, 0, buf.Length); // read from stream to byte array

이 확장 클래스를 사용합니다.

public static class StreamExtensions
{
    public static byte[] ReadAllBytes(this Stream instream)
    {
        if (instream is MemoryStream)
            return ((MemoryStream) instream).ToArray();

        using (var memoryStream = new MemoryStream())
        {
            instream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }
}

클래스를 솔루션에 복사하면 모든 스트림에서 사용할 수 있습니다.

byte[] bytes = myStream.ReadAllBytes()

모든 스트림에 적합하며 많은 코드를 저장합니다! 물론이 방법을 수정하여 필요한 경우 성능을 향상시키기 위해 다른 접근법을 사용하여 여기에서 다른 접근법을 사용 할 수 있지만 간단하게 유지하고 싶습니다.

Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);

좋아, 어쩌면 여기에 뭔가 빠졌어요.하지만 이것이 내가하는 방식입니다.

public static Byte[] ToByteArray(this Stream stream) {
    Int32 length = stream.Length > Int32.MaxValue ? Int32.MaxValue : Convert.ToInt32(stream.Length);
    Byte[] buffer = new Byte[length];
    stream.Read(buffer, 0, length);
    return buffer;
}

모바일 장치 또는 기타에서 파일을 게시하는 경우

    byte[] fileData = null;
    using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
    {
        fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
    }

빠르고 더러운 기술 :

    static byte[] StreamToByteArray(Stream inputStream)
    {
        if (!inputStream.CanRead)
        {
            throw new ArgumentException(); 
        }

        // This is optional
        if (inputStream.CanSeek)
        {
            inputStream.Seek(0, SeekOrigin.Begin);
        }

        byte[] output = new byte[inputStream.Length];
        int bytesRead = inputStream.Read(output, 0, output.Length);
        Debug.Assert(bytesRead == output.Length, "Bytes read from stream matches stream length");
        return output;
    }

테스트:

    static void Main(string[] args)
    {
        byte[] data;
        string path = @"C:\Windows\System32\notepad.exe";
        using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
        {
            data = StreamToByteArray(fs);
        }

        Debug.Assert(data.Length > 0);
        Debug.Assert(new FileInfo(path).Length == data.Length); 
    }

스트림의 내용을 복사하려면 BYTE []로 스트림을 BYTE []로 읽고 싶은 이유를 묻습니다. MemoryStream을 사용하고 입력 스트림을 메모리 스트림에 쓰는 것이 좋습니다.

Stream s;
int len = (int)s.Length;
byte[] b = new byte[len];
int pos = 0;
while((r = s.Read(b, pos, len - pos)) > 0) {
    pos += r;
}

약간 더 복잡한 솔루션은 필요합니다 s.Length 초과 Int32.MaxValue. 그러나 메모리에 큰 스트림을 읽어야한다면 문제에 대한 다른 접근 방식에 대해 생각할 수 있습니다.

편집 : 스트림이 지원하지 않는 경우 Length 속성, Earwicker 's를 사용하여 수정하십시오 해결 방법.

public static class StreamExtensions {
    // Credit to Earwicker
    public static void CopyStream(this Stream input, Stream output) {
        byte[] b = new byte[32768];
        int r;
        while ((r = input.Read(b, 0, b.Length)) > 0) {
            output.Write(b, 0, r);
        }
    }
}

[...]

Stream s;
MemoryStream ms = new MemoryStream();
s.CopyStream(ms);
byte[] b = ms.GetBuffer();

한 번에 파트를 읽고 반환되는 바이트 배열을 확장 할 수도 있습니다.

public byte[] StreamToByteArray(string fileName)
{
    byte[] total_stream = new byte[0];
    using (Stream input = File.Open(fileName, FileMode.Open, FileAccess.Read))
    {
        byte[] stream_array = new byte[0];
        // Setup whatever read size you want (small here for testing)
        byte[] buffer = new byte[32];// * 1024];
        int read = 0;

        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            stream_array = new byte[total_stream.Length + read];
            total_stream.CopyTo(stream_array, 0);
            Array.Copy(buffer, 0, stream_array, total_stream.Length, read);
            total_stream = stream_array;
        }
    }
    return total_stream;
}

"Bigenough"어레이는 약간의 스트레칭입니다. 물론, 버퍼는 "큰 ebough"여야하지만 애플리케이션의 적절한 설계에는 트랜잭션과 구분자가 포함되어야합니다. 이 구성에서 각 트랜잭션은 사전 설정 길이를 가지므로 배열은 특정 수의 바이트를 예상하고 올바르게 크기의 버퍼에 삽입합니다. 구분자는 거래 무결성을 보장하고 각 거래 내에 공급됩니다. 애플리케이션을 더 좋게하려면 2 개의 채널 (2 개의 소켓)을 사용할 수 있습니다. 하나는 데이터 채널을 사용하여 전송할 크기 및 시퀀스 수에 대한 정보를 포함하는 고정 길이 길이 제어 메시지 트랜잭션을 전달합니다. 수신기는 버퍼 생성을 인정하고 데이터 만 보내는 것입니다. 스트림 송신기를 제어 할 수없는 경우 버퍼로 다차원 배열이 필요합니다. 구성 요소 어레이는 예상 데이터의 추정치를 기반으로 실용적으로 관리하기에 충분히 작고 크게 작습니다. 프로세스 로직은 알려진 시작 구분자를 찾은 다음 후속 요소 어레이에서 구분기를 끝냅니다. 결말 구분 기호가 발견되면, 구분미터 사이에 관련 데이터를 저장하기 위해 새로운 버퍼가 생성되며 초기 버퍼는 데이터 처리를 허용하도록 재구성되어야합니다.

스트림을 바이트 배열로 변환하는 코드가 아래의 것입니다.

Stream s = yourStream;
int streamEnd = Convert.ToInt32(s.Length);
byte[] buffer = new byte[streamEnd];
s.Read(buffer, 0, streamEnd);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top