2016-08-04 3 views
1

파일을 분할하여 SQL Server에 업로드하는 업 로더가 있습니다. 그런 다음 각 청크를 다운로드하고 임시 파일을 만듭니다. 바이트 배열 (byte []) 목록을 하나의 파일에 작성하여 해당 파일을 다시 작성하려고합니다. 바이트 배열 목록을 하나의 배열로 읽으려고하면 OutOfMemory 예외가 발생하기 때문입니다. 이 작업을 수행하는 가장 좋은 방법은 무엇인지 궁금합니다. 감사!바이트 배열 목록을 파일에 쓰는 방법 C#

string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
     int currentRowSelection = fUS_FileDataGridView.CurrentCell.RowIndex; 
     var totalNumber = fUS_FileDataGridView.Rows[currentRowSelection].Cells[6].Value; 
     for (int i = 1; i < 149; i++) 
     { 
      using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read)) 
      { 
       using (var reader = new BinaryReader(stream1)) 
       { 
        list_.Add(reader.ReadBytes((int)stream1.Length)); 
        stream1.Close(); 
        stream1.Dispose(); 
        reader.Close(); 
        reader.Dispose(); 

       } 
      } 
     } 
     //array_ = list_.SelectMany(a => a).ToArray(); 

     filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip"; 
     foreach (byte[] bytes in list_) 
     { 
      var doc = System.Text.Encoding.Default.GetString(bytes); 
      string textToAdd1 = bytes.ToString(); 
      try 
      { 
       using (FileStream fs = File.Create(filePaths_)) 
       using (StreamWriter writer = new StreamWriter(fs, Encoding.Default, 512)) 
       { 
        writer.Write(textToAdd1); 
        writer.Close(); 
        writer.Dispose(); 
       } 
      } 
      finally 
      { 
      } 
     } 
    } 

업데이트 : 내 질문에 내가 파일을 작성하는 하나의 배열로 바이트 배열의 내 목록을 넣을 수 없기 때문에 내가 찾은 다른 사람과 다르다. 현재 100KB 파일을 가져와야하는 코드에서 1KB 파일 만 가져옵니다.

업데이트 2 : 아래의 코드는 훨씬 더 의미가 있지만, 지금은

filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip"; 
     using (FileStream fs = File.Create(filePaths_)) 
     for (int i = 0; i < 151; i++) 
     { 
      using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read)) 
      { 
       using (var reader = new BinaryReader(stream1)) 
       { 
        using (StreamWriter writer = new StreamWriter(fs, Encoding.Default, 512)) 
        { 
         writer.Write(reader); 
        } 
       } 
      } 
     } 
+3

http://stackoverflow.com/questions/381508/can-a-byte-array-be-written-to-a-file-in-c –

+0

@NarekArzumanyan 해당 페이지의 아무 것도 "List "을 쓸 수 없습니다. 그래도 파일일까요? 나는 메모리 부족 예외가 발생하기 때문에 그것을 하나의 배열에 넣을 수 없다. – TWelles1

+0

가능한 중복 [C# 바이트 배열을 기존 파일에 추가] (http://stackoverflow.com/questions/6862368/c-sharp-append-byte- array-to-existing-file) – sr28

답변

0

"스트림이 쓰기 오류 아니었다"는 무엇입니까 난 지금 당신이 원하는 게 무엇인지 이해하는 경우 :

// Fill list_ 
List<byte[]> list_ = null; 
// .... 

string filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip"; 
// Create FileStream and BinaryWriter 
using (var fs = File.OpenWrite(filePaths_)){ 
    using (var bw = new BinaryWriter(fs)){ 
     foreach (var bytes in list_) 
      bw.Write(bytes); // Write each byte array to the stream 
    } 
} 

업데이트 됨. 당신은 다른 직접 복사에게 더 나은 방법으로 하나 개의 스트림을 그것을 할 수 있습니다 : 문제가 메모리가 부족

string filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip"; 
// Result FileStream and BinaryWriter 
using (var fs = File.OpenWrite(filePaths_)) 
{ 
    for (int i = 1; i < 149; i++) 
    { 
     using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read)) 
     { 
      // Just copy stream1 to fs 
      stream1.CopyTo(fs); 
     } 
    } 
} 
2

경우에 당신은 사용중인 메모리의 양을 줄이는 방법에 대해 생각해야한다.

요구 사항이 무엇인지 모르겠지만 제공 한 코드를 기반으로 작성한 첫 번째 foreach 루프 내에서 모든 작업을 수행 할 수 있습니다. 이렇게하면 한 번에 하나의 파일 만로드되며 각 파일을 완료하면 GC가 메모리를 비 웁니다.

using (FileStream fs = File.AppendText(filePaths_)) 
    { 
     for (int i = 1; i < 149; i++) 
     { 
      using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read)) 
      { 
       using (var reader = new BinaryReader(stream1)) 
       { 
        //list_.Add(reader.ReadBytes((int)stream1.Length)); 
        //Instead of adding that to list, write them to disk here 
        //fs.Write(...) 
        //... 


        stream1.Close();//No need for this, using is going to call it. 
        stream1.Dispose();//No need for this, using is going to call it. 
        reader.Close();//No need for this, using is going to call it. 
        reader.Dispose();//No need for this, using is going to call it. 

       } 
      } 
     } 
    } 
+0

모든 파일은 하나의 파일에 결합되어 있으므로'for (FileStream fs = File.Create (filePaths _))'는'for' 루프 외부에 있어야합니다. –

+0

@ScottChamberlain 좋은 캐치 – Steve

+0

위의 코드를 사용했는데 메모리 예외가 발생하지 않았지만 1KB 파일 만있었습니다 (훨씬 커야 함). 나는 이것을 조금 더 살펴볼 것이다. (벌써 3 일 동안 이걸 쳐다 보았다.) 너희들에게 돌아 가자. 감사! – TWelles1

0

기존 파일에 각 바이트 배열을 추가하는 것이 효과적이라고 생각됩니다. 그래서 나는 각 개별 배열을 파일에 쓰고 싶을 때 FileMode.Open 대신 FileMode.Append을 사용하여 파일 스트림을 간단하게 열 것이라고 생각합니다.