C#에서 스트림을 바이트[]로 변환하려면 어떻게 해야 합니까?
간단한 변환 방법이나 방법이 있습니까?Stream
의 상태가.byte[]
C#에?
내가 아는 가장 짧은 해결책은:
using(var memoryStream = new MemoryStream())
{
sourceStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
다음 함수 호출:
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;
}
}
}
다음 확장 클래스를 사용합니다.
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()
모든 스트림에 적합하고 코드를 많이 절약합니다!물론 필요한 경우 성능을 개선하기 위해 여기에 있는 다른 접근 방식 중 일부를 사용하도록 이 방법을 수정할 수 있지만, 저는 단순하게 유지하는 것을 좋아합니다.
.NET Framework 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
편집: 원래 저는 제이슨의 답변을 사용할 것을 제안했습니다.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[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);
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 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);
}
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의 해결 방법을 사용하여 수정합니다.
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;
}
"충분히 큰" 배열은 약간의 확장입니다.물론 버퍼는 "크게" 되어야 하지만 응용프로그램의 적절한 설계에는 트랜잭션과 구분 기호가 포함되어야 합니다.이 구성에서는 각 트랜잭션의 길이가 미리 설정되므로 어레이가 특정 바이트 수를 예상하고 올바른 크기의 버퍼에 삽입합니다.구분 기호는 트랜잭션 무결성을 보장하며 각 트랜잭션 내에서 제공됩니다.응용 프로그램을 더욱 향상시키기 위해 2개의 채널(2 소켓)을 사용할 수 있습니다.하나는 데이터 채널을 사용하여 전송할 데이터 트랜잭션의 크기 및 시퀀스 번호에 대한 정보를 포함하는 고정 길이 제어 메시지 트랜잭션을 전달합니다.수신기는 버퍼 생성을 승인하고 데이터를 전송합니다.스트림 발신인에 대한 제어 권한이 없는 경우 버퍼로 다차원 배열이 필요합니다.구성 요소 어레이는 관리가 가능할 정도로 충분히 작고 예상 데이터를 기반으로 실용적일 수 있을 정도로 충분히 큽니다.프로세스 논리는 알려진 시작 구분 기호와 후속 요소 배열의 끝 구분 기호를 찾습니다.종료 구분 기호가 발견되면 구분 기호 간에 관련 데이터를 저장할 새 버퍼가 생성되고 데이터 처리를 허용하도록 초기 버퍼를 재구성해야 합니다.
스트림을 바이트 배열로 변환하는 코드는 아래와 같습니다.
Stream s = yourStream;
int streamEnd = Convert.ToInt32(s.Length);
byte[] buffer = new byte[streamEnd];
s.Read(buffer, 0, streamEnd);
빠르고 더러운 기술:
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);
}
스트림의 내용을 복사하려면 메모리 스트림을 사용하여 입력 스트림을 메모리 스트림에 쓰는 것이 좋습니다.
언급URL : https://stackoverflow.com/questions/1080442/how-do-i-convert-a-stream-into-a-byte-in-c
'programing' 카테고리의 다른 글
인라인 CSS에서 'a:hover'를 어떻게 쓸 수 있습니까? (0) | 2023.05.21 |
---|---|
스택과 힙은 무엇이며 어디에 있습니까? (0) | 2023.05.21 |
Github에서 저장소를 폴더로 정렬할 수 있습니까? (0) | 2023.05.21 |
Twitter 부트스트랩 모달 창 닫기 허용 안 함 (0) | 2023.05.21 |
프로비저닝 프로파일에 애플리케이션-식별자 및 키체인-액세스-그룹 자격이 포함되지 않음 (0) | 2023.05.21 |