2013-03-25 109 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')

相关问题