2011-08-23 7 views
1

파일을 바이트로 변환하여 나중에 인터넷을 통해 보낼 수있는 방법이 있습니다. 어쨌든 큰 파일을 보내려고하기 때문에 전체 파일을 보내는 대신 파일 덩어리를 보냅니다. 각 청크는 바이트 배열 (byte [])로 구성됩니다. 나는이 모든 것에 익숙하지 않기 때문에 각 청크를 보내기 전에 청크 목록에 저장하고 싶었다. \ 사용자새 데이터를 추가 할 때 목록 항목이 변경됩니다 ... 이유가 무엇입니까?

t.iso 토노 \ 바탕 화면 \를 \ :

public class SomeClass 
{ 

    public List<byte[]> binaryFileList; 

    public void SendChunk(byte[] data, int index) 
    { 
     binaryFileList.Add(data); 
     // later I will add code in here to do something with data 
    } 

    public void test(string path) 
    { 
     binaryFileList = new List<byte[]>(); 

     System.IO.FileStream stream = new System.IO.FileStream(path, 
      System.IO.FileMode.Open, System.IO.FileAccess.Read); 

     var MaxChunkSize = 10000; 
     byte[] chunk = new byte[MaxChunkSize]; 
     while (true) 
     { 
      int index = 0; 
      // There are various different ways of structuring this bit of code. 
      // Fundamentally we're trying to keep reading in to our chunk until 
      // either we reach the end of the stream, or we've read everything we need. 
      while (index < chunk.Length) 
      { 
       int bytesRead = stream.Read(chunk, index, chunk.Length - index); 

       if (bytesRead == 0) 
       { 
        break; 
       } 
       index += bytesRead; 
      } 
      if (index != 0) // Our previous chunk may have been the last one 
      { 
       SendChunk(chunk, index); // index is the number of bytes in the chunk 
      } 
      if (index != chunk.Length) // We didn't read a full chunk: we're done 
      { 
       return; 
      } 
     } 


    } 
} 

내가 실행할 때 : A :

SomeClass s = new SomeClass(); 
s.test(@"A:\Users\Tono\Desktop\t.iso"); 

binaryFileList 목록 파일의 덩어리로 채워됩니다 같은 내 수업 보인다

이제 데이터를 묶어서 파일을 만들 때 문제가 발생했습니다. 디버깅 할 때 데이터를 입력 할 때 binaryFileList의 항목이 변경되어 문제가 있음을 발견했습니다. 내가 무슨 뜻인지 보여 드리겠습니다 :이 디버그에 내가 binaryFileList에 항목을 추가 처음이다

enter image description here

사항. 또한 배열의 해당 항목의 각 바이트를 볼 수 있습니다 ...

이제 메소드를 binaryFileList에 더 많은 항목을 추가하여 실행하도록합니다.

그래서 지금 binaryFileList가 278 개 항목 대신 마지막 사진에서와 같은 하나

enter image description here

때문에 모든 것을 지금까지 확인 오른쪽 보인다? 하지만 binaryFileList의 첫 번째 항목에는 거의 모든 0이 포함 된 바이트 배열이 포함되어 있다는 것을 기억하십니까?

enter image description here

을 내가 항목을 계속 추가로 첫 번째 항목 변경 방법주의 binaryFileList하기 : binaryFileList의 첫 번째 항목에서 살펴 즉

enter image description here

이 binaryFileList가리스트 바이트 []의 binaryFileList에 byte []를 추가하면 다른 byte []가 변경되어서는 안됩니다. 그들은 변화한다! 왜!?

답변

2

다음 줄은 루프 내부에 가야한다 :

byte[] chunk = new byte[MaxChunkSize]; 

당신은 한 번만 덩어리를 만들고 그것을 새로운 데이터마다 덮어 씁니다. 목록에 저장하는 내용은이 청크에 대한 참조 일 뿐이며 사본이 아닙니다.

1

stream.Read으로 전화 할 때 과 동일한 참조 번호 chunk을 사용하고 있습니다.

0

내 생각에 SendChunk 메서드에 전달할 바이트 배열을 다시 사용하고있을 것입니다. 배열은 참조 형식이므로 각 메서드 호출에 대해 새 바이트 배열을 만들어야합니다.

1

매번 같은 청크로 읽고 매번 가장 최근 값을 가진 동일한 청크를 목록에 추가하고 있습니다.당신이 새로운 바이트 []마다 작성해야 해결하려면 : 각 목록 위치에 동일한 개체에 동일한 기준을두고 배열에 버퍼 변수를 추가 계속

while (true) 
    { 
     // *** need to create new array each time... 
     var chunk = new byte[MaxChunkSize]; 

     int index = 0; 
     // There are various different ways of structuring this bit of code. 
     // Fundamentally we're trying to keep reading in to our chunk until 
     // either we reach the end of the stream, or we've read everything we need. 
     while (index < chunk.Length) 
     { 
      int bytesRead = stream.Read(chunk, index, chunk.Length - index); 

      if (bytesRead == 0) 
      { 
       break; 
      } 
      index += bytesRead; 
     } 
     if (index != 0) // Our previous chunk may have been the last one 
     { 
      SendChunk(chunk, index); // index is the number of bytes in the chunk 
     } 
     if (index != chunk.Length) // We didn't read a full chunk: we're done 
     { 
      return; 
     } 
    } 
+0

제임스 나는 그 방법을 가지고 있습니다 : http://stackoverflow.com/questions/5659189/how-to-split-a-large-file-into-chunks-in-c/5659258#5659258 그리고 그 파일은 다음 번에 Read 메서드를 호출하면 다음 바이트를 읽습니다. 그 방법은 데이터 라이트를 쓸 때 작동합니다 ... –

+0

누가 투표를했는데, 그 이유는 무엇입니까? 우리 중 많은 사람들이 같은 대답을하면서 동시에 대답했습니다. 아래 표를 얻고 이유를 모른다고 생각합니다. –

+0

@ 토 노 : 네,하지만 지금 당장 사용하지 않고 있습니다. 목록에 저장 한 다음 arround를 반복합니다. 배열은 한 번 생성되고 (이론상의 위치 1000에서 말함) 바이트 배열 @ 1000에 대한 참조가 목록에 푸시됩니다. 루프를 돌면서 다시 읽으면 새로운 바이트를 위치 1000의 바이트 []로 다시 읽습니다! 이게 문제 야. 어딘가에 저장하려면 (또는 목록에 추가하기 전에 복제하려면) 새 바이트 []가 필요합니다. 어느 쪽이든 저장하려는 각각의 배열을 만들어야합니다. –

0

.

새 바이트 []를 할당하고 버퍼 배열을 새 배열에 복사하거나 읽는 각 청크에 대해 새 버퍼 배열을 교대로 할당해야합니다.

여기에 내가 당신이 더 문제를 이해하기 위해 읽어 제안 에릭 Lippert의에 의해 참조에 탁월한 두 부분으로 게시물 : 당신은 청크 배열을 할당하기 때문에

http://blogs.msdn.com/b/ericlippert/archive/2011/03/07/references-and-pointers-part-one.aspx

http://blogs.msdn.com/b/ericlippert/archive/2011/03/10/references-and-pointers-part-two.aspx

0

문제는 한 번만 :

byte[] chunk = new byte[MaxChunkSize];

그리고 같은 배열에 파일의 새로운 부분을 계속해서 읽고 있습니다. 배열은 메서드 매개 변수에서 참조로 전달됩니다. 루프 내에서 선언을 이동하면 정상이어야합니다.

관련 문제