2014-12-05 68 views
2

關於此交Stream read selected listbox item query雷丁400字節的二進制文件頭文件

我正在讀SEGY文件(地震數據),並與交上述我管理讀取第一3200個字節,這是考文件頭文件的一個SEGY文件。

http://en.wikipedia.org/wiki/SEG_Y http://www.seg.org/documents/10161/77915/seg_y_rev1.pdf

我想下一步要做的就是讀它而來的3200個字節texual文件頭後的400字節的二進制文件頭。

我修改了我的代碼,嘗試讀取文件並跳過第一個3200字節,但它提出了拒絕訪問的異常,我不明白爲什麼,我可以讀取texual頭文件,我認爲它確實是一個訪問問題。我懷疑這是我如何設置二進制閱讀。 (我發現訪問問題,我沒有關閉從文本標題中讀取的文件)

當我讀取二進制文件後,我想將其轉換爲可讀文本並在富文本框中顯示,但不幸的是,由於我用C#修改了有限的5個月,這超出了我的能力。

任何幫助,將不勝感激,謝謝。

char[] binary = new char[400]; 

String item = (string)txtPath.Text + @"\" + lstFiles.SelectedItem; 
      FileStream readStream; 
      try 
      { 
       readStream = new FileStream(item, FileMode.Open); 
       BinaryReader readBinary = new BinaryReader(readStream); 
       readBinary.BaseStream.Seek(0, SeekOrigin.Begin); 
       readBinary.Read(binary, 3200, 400); 
       string stringData = ""; 

       for (int i = 0; i < data.Length; i++) 
       { 
        if ((i % 80) == 0 && stringData != "") 
         stringData += Environment.NewLine; 
        stringData += data[i].ToString(); 
       } 
       rtbHeader.Text = stringData + Environment.NewLine; 
       rtbHeader.AppendText(item); 
       readStream.Close(); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
      } 
+0

給我們確切的異常信息以及你得到它的哪一行會有所幫助。 – 2014-12-05 06:15:38

回答

1

Read方法不能像那樣工作。

你已經試過這樣:

readBinary.Read(binary, 3200, 400); 

這將讀取400個字節當前文件指針但隨後開始在陣列偏移3200

根據你的描述,這不是你想要的。

而是,手動跳過第一3200個字節,則該參數指定爲0:

readStream = new FileStream(item, FileMode.Open); 
BinaryReader readBinary = new BinaryReader(readStream); 
readBinary.BaseStream.Seek(3200, SeekOrigin.Begin); 
readBinary.Read(binary, 0, 400); 

documentation of BinaryReader.Read

索引
,緩衝區中的起點處開始讀入緩衝區。

+0

嗨@LasseeVKarlsen感謝您的迴應,我試過你的例子,但唯一的輸出是從這行rtbHeader.AppendText(項目)的文件名; from String item =(string)txtPath.Text + @「\」+ lstFiles.SelectedItem;我假設我應該在RTB中看到不可讀的文字?這導致我另一個問題(我已經明確了我的帖子)如何將我的代碼轉換爲讀取二進制文件並以人類可讀形式顯示?我在網頁http://www.dotnetperls.com/binaryreader的編碼標題下找到了此頁面,它顯示了使用ASCII編碼讀取二進制文件的示例,但它不起作用。 – Exception 2014-12-07 23:19:58

+0

我的答案是否奏效,是否從位置3200讀取了400個字節,或者沒有? – 2014-12-08 06:33:29

+0

嗨Lassee,我沒有輸出,也沒有說你的建議有什麼問題,但我無法讓它工作。我會繼續玩它。 – Exception 2014-12-08 22:57:54

0

我想你需要仔細閱讀400字節二進制文件頭記錄的定義:它們被定義爲雙字節或四字節,二進制補碼整數。如3201-3204,這是四字節,3213-3214,這是兩字節。除此之外,segy文件是IBM的大端數據。我認爲你需要在Windows操作系統上將big-endian轉換成little-endian。

0

我不是一個真正的程序員,我是用C#亂搞,並寫了下面的代碼讀取SEGY文件的二進制頭,我希望這可以給你一些提示:

namespace SEGY_TEST 
{ 
    class BinaryHeader 
    { 
     string fname; 
     public int si; 
     public int spt; 
     public int fc; 
     public string sfc; 
     public int bytef; // byte format. 
    public BinaryH(string fname) 
    { 
     this.fname = fname; 
     this.lee(); 
     this.segyformat(this.fc); 


     //Console.WriteLine("Abriendo {0}", this.fname); 
    } 


    public void segyformat(int fc) 
    { 
     switch (this.fc) 
     { 
      case 1: 
       this.bytef = 4; 
       this.sfc= "IBM-FLOAT"; 
       break; 
      case 3: 
       this.bytef = 2; 
       this.sfc = "INT-16"; 
       break; 

      case 5: 
       this.bytef = 4; 
       this.sfc = "IEEE-FLOAT"; 
       break; 
      case 8: 
       this.bytef = 1; 
       this.sfc = "INT-8"; 
       break; 

      default: 

       while (true) 
       { 
        Console.WriteLine("{0} -- FORMAT NOT SUPPORTED PLEASE EXIT",this.fc); 
        Console.Read(); 
       } 


     } 
    } 

    public void lee() 
    { 
     byte[] datos=new byte[400]; 
     using (FileStream readFile = new FileStream(this.fname, 
      FileMode.Open, FileAccess.Read)) 
     { 
      readFile.Seek(3200, SeekOrigin.Begin); 
      readFile.Read(datos, 0, 400); 
      readFile.Close(); 
     } 

     this.si = Endiann.BE16ToInt16(datos, 16); // sample interval 
     this.spt = Endiann.BE16ToInt16(datos, 20); // samples per trace 
     this.fc = Endiann.BE16ToInt16(datos, 24); // format code 

     //Console.WriteLine("{0} sample interval",si); 
     //Console.WriteLine("{0} sample per trace", spt); 
     //Console.WriteLine("{0} Fomrmat code", fc); 

    } 
} 
} 

    public static int BE16ToInt16(byte[] buf, int i) 
    { 
     return (Int16)((buf[i] << 8) | buf[i + 1]); 
    }