입력 스트림에서 바이트 배열을 만드는 데 선호되는 방법은 무엇입니까?
다음은 .NET 3.5의 현재 솔루션입니다.
Stream s;
byte[] b;
using (BinaryReader br = new BinaryReader(s))
{
b = br.ReadBytes((int)s.Length);
}
스트림 덩어리를 읽고 쓰는 것이 여전히 더 좋은 아이디어입니까?
답변
그것은 당신이 믿을 수 있는지 아닌지에 달려 있습니다 s.Length
. 많은 스트림의 경우 얼마나 많은 데이터가 있는지 알 수 없습니다. 이러한 경우-.NET 4 이전-다음과 같은 코드를 사용합니다.
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
.NET 4 이상으로, 내가 사용하는 거라고 Stream.CopyTo
만들기 – 내 코드에서 루프 기본적으로 동등한 인 MemoryStream
, 전화를 stream.CopyTo(ms)
한 후 반환 ms.ToArray()
. 작업이 완료되었습니다.
왜 내 답변이 다른 답변보다 긴지 설명해야합니다. Stream.Read
요청한 모든 내용을 읽도록 보장하지는 않습니다. 예를 들어 네트워크 스트림에서 읽는 경우 더 많은 데이터가 있더라도 하나의 패킷 가치를 읽은 다음 반환 될 수 있습니다. BinaryReader.Read
스트림이 끝날 때까지 또는 지정된 크기까지 계속 진행되지만 시작하려면 크기를 알아야합니다.
위의 방법은 MemoryStream
데이터가 부족해질 때까지 계속 읽고 읽 습니다. 그런 다음 MemoryStream
데이터의 복사본을 배열로 반환 하도록 요청합니다 . 크기를 시작으로 알고 있거나 확실하지 않은 경우 크기를 알고 있다고 생각되면를 시작 MemoryStream
하기 위해 해당 크기가되도록 구성 할 수 있습니다 . 마찬가지로 끝에 검사를 할 수 있으며 스트림의 길이가 버퍼와 크기가 같으면 (로 반환 MemoryStream.GetBuffer
) 버퍼를 반환 할 수 있습니다. 따라서 위의 코드는 최적화되지 않았지만 적어도 정확합니다. 스트림을 닫을 책임은 없습니다. 호출자가 그렇게해야합니다.
자세한 내용 및 대체 구현에 대해서는 이 기사 를 참조하십시오 .
답변
Jon의 답변은 정확하지만 이미 존재하는 코드를 다시 작성하고 있습니다 CopyTo
. 따라서 .Net 4의 경우 Sandip 솔루션을 사용하지만 이전 버전의 .Net의 경우 Jon의 답변을 사용하십시오. Sandip의 코드는 CopyTo
많은 상황에서 예외가 있을 가능성이 높고 MemoryStream
폐기되지 않은 채 “사용”을 사용하여 개선 될 것 입니다.
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
답변
이미 가지고있는 MemoryStream이있는 memorystream.ToArray()
경우 지적하십시오.
또한 알려지지 않은 또는 다른 하위 유형의 스트림을 처리하고 있고를 수신 MemoryStream
할 수있는 경우 해당 경우에 대해 상기 방법을 중계하고 다른 방법에 대해 여전히 허용 된 답변을 사용할 수 있습니다.
public static byte[] StreamToByteArray(Stream stream)
{
if (stream is MemoryStream)
{
return ((MemoryStream)stream).ToArray();
}
else
{
// Jon Skeet's accepted answer
return ReadFully(stream);
}
}
답변
MemoryStream ms = new MemoryStream();
file.PostedFile.InputStream.CopyTo(ms);
var byts = ms.ToArray();
ms.Dispose();
답변
내 커플 센트 … 내가 자주 사용하는 연습은 이와 같은 방법을 사용자 정의 도우미로 구성하는 것입니다.
public static class StreamHelpers
{
public static byte[] ReadFully(this Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
}
구성 파일에 네임 스페이스를 추가하고 원하는 곳에서 사용하십시오.
답변
예를 들어 MemoryStream 클래스의 ToArray () 메서드를 사용할 수 있습니다.
MemoryStream ms = (MemoryStream)dataInStream;
byte[] imageBytes = ms.ToArray();
답변
확장 기능으로 더 멋지게 만들 수도 있습니다.
namespace Foo
{
public static class Extensions
{
public static byte[] ToByteArray(this Stream stream)
{
using (stream)
{
using (MemoryStream memStream = new MemoryStream())
{
stream.CopyTo(memStream);
return memStream.ToArray();
}
}
}
}
}
그런 다음 일반 메소드로 호출하십시오.
byte[] arr = someStream.ToByteArray()