2013-03-25 110 views
3

我有一個混合文件,有很多字符串行和字節編碼數據的一部分。 實施例:如何讀取字節和字符串的混合文件

--Begin Attach 
Content-Info: /Format=TIF 
Content-Description: 30085949.tif (TIF File) 
Content-Transfer-Encoding: binary; Length=220096 
II*II* Îh ÿÿÿÿÿÿü³küìpsMg›Êq™Æ™Ôd™‡–h7ÃAøAú áùõ=6?Eã½/ô|û ƒú7z:>„Çÿý<þ¯úýúßj?å¿þÇéöûþ「«ÿ¾ÁøKøÈ%ŠdOÿÞÈ<,Wþ‡ÿ·ƒïüúCÿß%Ï$sŸÿÃÿ÷‡þåiò>GÈù#ä|‘ò:#ä|Š":#¢:;ˆèŽˆèʤV‘ÑÑÑÑÑÑÑÑÑçIþ×o(¿zHDDDDDFp'.Ñ:ˆR:aAràÁ¬LˆÈù!ÿÿï[ÿ¯Äàiƒ"VƒDÇ)Ê6PáÈê$9C」9C†‡CD¡[email protected]¦œÖ{i~Úý¯kköDœ4ÉU」8`ƒt!l2G 
--End Attach-- 

我嘗試讀取文件與StreamReader的:

string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Davide\Desktop\20041230000D.xmm") 

我逐行讀取的文件,並且當線等於「內容傳輸編碼:二進制;長度= 220096 「,我讀了所有以下行並寫入一個」文件名「(在這種情況下爲30085949.tif)文件。 但我正在閱讀字符串,而不是字節數據和結果文件已損壞(現在我試着用tiff文件)。對我有何建議?

解決方案 感謝您的回覆。我已經採用了這種解決方案:我建造了一座LineReader延長BinaryReader在:

public class LineReader : BinaryReader 
    { 
     public LineReader(Stream stream, Encoding encoding) 
      : base(stream, encoding) 
     { 

     } 

     public int currentPos; 
     private StringBuilder stringBuffer; 

     public string ReadLine() 
     { 
      currentPos = 0; 

      char[] buf = new char[1]; 

      stringBuffer = new StringBuilder(); 
      bool lineEndFound = false; 

      while (base.Read(buf, 0, 1) > 0) 
      { 
       currentPos++; 
       if (buf[0] == Microsoft.VisualBasic.Strings.ChrW(10)) 
       { 
        lineEndFound = true; 
       } 
       else 
       {     
        stringBuffer.Append(buf[0]);      
       } 
       if (lineEndFound) 
       { 
        return stringBuffer.ToString(); 
       } 

      } 
      return stringBuffer.ToString(); 

     } 

    } 

Microsoft.VisualBasic.Strings.ChrW(10)是換行。 當我分析我的文件:

using (LineReader b = new LineReader(File.OpenRead(path), Encoding.Default)) 
    { 
     int pos = 0; 
     int length = (int)b.BaseStream.Length; 
     while (pos < length) 
     { 
      string line = b.ReadLine(); 
      pos += (b.currentPos); 

      if (!beginNextPart) 
      { 
       if (line.StartsWith(BEGINATTACH)) 
       { 
        beginNextPart = true; 

       } 
      } 
      else 
      { 
       if (line.StartsWith(ENDATTACH)) 
       { 
        beginNextPart = false; 
       } 
       else 
       { 
        if (line.StartsWith("Content-Transfer-Encoding: binary; Length=")) 
        { 
         attachLength = Convert.ToInt32(line.Replace("Content-Transfer-Encoding: binary; Length=", "")); 
         byte[] attachData = b.ReadBytes(attachLength); 
         pos += (attachLength); 
         ByteArrayToFile(@"C:\users\davide\desktop\files.tif", attachData); 
        } 
       } 
      } 
     } 
    } 

我從文件中讀取的字節長度和我讀到以下n個字節。

+0

你可以嘗試手動讀取文件內容使用'StreamReader'爲字符串和'BinaryReader'爲二進制數據... – 2kay 2013-03-25 11:46:36

+0

看起來功能 - 我只是希望你的基礎流被緩衝(可能是)或你的表現將遭受所有這些簡短的閱讀。另外,''\ n''是C#(和所有類C語言)中表示與'Microsoft.VisualBasic.Strings.ChrW(10)'相同的值的慣用方式,並且還具有常量不是函數調用。 – MattW 2013-03-26 13:06:31

+0

Thanks @MattW,對於'\ n',你的意思是我的比較成爲'buf [0] =='\ n''?我不明白緩衝區問題。請用一個例子來解釋我。 – davymartu 2013-03-26 13:41:20

回答

3

這裏你的問題是,一個StreamReader假定它是唯一讀取文件,因此它提前讀取。您最好的選擇是將文件讀取爲二進制文件,並使用適當的文本編碼從您自己的緩衝區中檢索字符串數據。

因爲顯然你不介意整個文件讀入內存,你可以用一個開始:

byte[] buf = System.IO.File.ReadAllBytes(@"C:\Users\Davide\Desktop\20041230000D.xmm"); 

然後假設你使用UTF-8爲您的文本數據:

int offset = 0; 
int binaryLength = 0; 
while (binaryLength == 0 && offset < buf.Length) { 
    var eolIdx = Array.IndexOf(offset, 13); // In a UTF-8 stream, byte 13 always represents newline 
    string line = System.Text.Encoding.UTF8.GetString(buf, offset, eolIdx - offset - 1); 

    // Process your line appropriately here, and set binaryLength if you expect binary data to follow 

    offset = eolIdx + 1; 
} 

// You don't necessarily need to copy binary data out, but just to show where it is: 
var binary = new byte[binaryLength]; 
Buffer.BlockCopy(buf, offset, binary, 0, binaryLength); 

如果您期望Window樣式的行結束符,您可能還想要執行line.TrimEnd('\r')

相關問題