2013-08-06 3 views
0

이미지를 보내는 방법에 대한 이전 질문에 도움을 받았습니다. 완료 한 것은 처음에 이미지의 크기 (크기)를 전송 한 다음 실제 이미지를 전송 한 다음 완료되었을 때 알 수있었습니다.NetworkStream 내 코드에서 이해할 수없는 것

IT는 다음과 같습니다 : 내 이전 질문에서 저를 도와 안젤로 Geels :

BinaryWriter writer = new BinaryWriter(netStream); 
while (someCondition) { 
    Image img = SomeImage(); 
    MemoryStream ms = new MemoryStream(); 
    img.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 
    byte[] buffer = new byte[ms.Length]; 
    ms.Seek(0, SeekOrigin.Begin); 
    ms.Read(buffer, 0, buffer.Length); 
    writer.Write(buffer.Length); 
    writer.Write(buffer); 

이 코드에서입니다.

이제는이 방법으로 최적화하려고했습니다. 그리고 잘 작동합니다. 그러나 파일이 bmp (압축되지 않은 경우) 일 때만, 나는 이유를 알지 못합니다.

    using (MemoryStream ms = PrintWindow(process)) 
        { 
         writer.Write((int)ms.Length); 
         writer.Write(ms.GetBuffer()); 
        } 

그래서 PrintWindow는 이미지를 memorystream에 저장하고 반환합니다. 그래서 ms = memorystream에 내 이미지가 있습니다.

그래서 나를 위해 이것은 완벽하게 작동해야합니다. 나는 똑같은 일을 할 수있는 형태를 만듭니다.

나는 파일의 크기 (memorystream의 길이)를 보냅니다. 그런 다음 memorystream에서 byte [] 데이터를 보냅니다.

그래서, 똑같습니다.

하지만 bmp에서만 작동합니다.

내가 생각할 수있는 유일한 점은 압축 된 형식으로 저장하면 bmp가 먼저 작성되고 다음에 인코딩되어 getbuffer() 또는 다른 것을 엉망으로 만듭니다.

하지만 여전히 작동해야한다고 생각합니다.

+0

해당 코드 블록에서의 사용 부족은 필자에게 깊은 걱정입니다. – Xcelled194

답변

3

쓰기가 너무 많은 Write() 오버로드를 사용하면 너무 많은 바이트를 쓸 수 있습니다.

using (MemoryStream ms = PrintWindow(process)) { 
     writer.Write((int)ms.Length); 
     writer.Write(ms.GetBuffer(), 0, (int)ms.Length); 
    } 
+0

위대한 작품, 그리고 왜 내가 그것의 모양에서 바이트 배열로 변환하지 않아도됩니다. 감사합니다 :) – Zerowalker

+0

btw, 거기에 더 그것을 최적화하는 방법 isn't? 내 말은, 파일 앞에 파일의 길이를 써야하므로 어디서 끝내야하는지 알 수 있습니다. 이걸 어떻게 든 개선 할 수 있습니까? – Zerowalker

+0

@ user2587718 바이트 배열로 변환하지 않았습니다. 대신, 당신은 ms 밖에서 청크를 읽고, 임시 버퍼에 넣은 다음, 그것을 쓰고있었습니다. 당신은 FAR에 대해 "최적화"에 대해 너무 많이 걱정하고 있으며, 당신은 잘못된 것을 "최적화"하고 있습니다. 성능 문제가 발생하는 경우 프로파일 러를 잡아 자신이 어디에 있는지 확인하십시오. 실제로이 코드 부분에 있다면 C#을 더 많이 사용하지 않고 모국어로 이동하면 성능이 향상됩니다. – Xcelled194

2

GetBuffer를 사용하지 마십시오. 문서에서 :

버퍼에는 사용되지 않은 할당 된 바이트가 들어 있습니다. 예를 들어 문자열 "test"가 MemoryStream 개체에 기록 된 경우 GetBuffer에서 반환 된 버퍼의 길이는 이 아닌 256이며 사용되지 않은 바이트는 252 바이트입니다. 버퍼의 데이터 만 얻으려면 ToArray 메서드를 사용하십시오. 그러나 ToArray는 메모리에 데이터 복사본을 만듭니다.

사용 :

writer.Write(ms.ToArray()); 

또는 4.0에있는 경우에 사용하는 CopyTo 방법 사용 : 당신이 스트림을 복사하는 방법을 4.0에없는 경우

ms.CopyTo(netStream); 

확인이 : How do I copy the contents of one stream to another?

+0

하지만 어떻게 bmp로 작동하고 압축되지 않습니까? ToArray가 복사본을 만들 때 (더 느리게?) GetBuffer? 시도해 보니 훨씬 느립니다.그리고 나는 "Hickups"를 때때로 2ms에서 12ms로 진행하는 프로세스 시간에 얻습니다. GetBuffer는 항상 0-2ms입니다. – Zerowalker

+0

@ user2587718 그것은 기본적으로 투명 한 운에 의해 작동합니다. GetBuffer 및 ToArray는 ** 교환 할 수 없습니다 **. – Xcelled194

+0

나는 4.5에 있지만, 그 방법으로 networkstream에 직접 쓸 수 있습니까? 바이너리/라이터없이 어디에서 끝낼지를 안다면 어떻게 될까요? – Zerowalker