在SEGY文件中读取400字节的二进制文件头

时间:2014-12-05 06:08:07

标签: c# binaryfiles

关于这篇文章Stream read selected listbox item query

我正在阅读一个SEGY文件(地震数据),上面的帖子我正在设法读取第一个3200字节,即SEGY文件的文本文件头。

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

我接下来要做的是读取3200字节文本文件头之后的400字节二进制文件头。

我修改了我的代码以尝试读取文件并跳过前3200字节,但是它出现了拒绝访问权限的例外情况,我不明白为什么,我可以阅读texual标题很好所以我不认为它真的是一个访问问题。我怀疑它是如何设置二进制读数的。 (我发现访问问题,我没有从文本标题中读取文件)

在我阅读完二进制文件后,我想将其转换为可读文本并在富文本框中显示,但不幸的是,我有限的5个月修补了C#它超出我的能力。

任何帮助都将不胜感激,谢谢。

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());
            }

3 个答案:

答案 0 :(得分: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

  

<强>索引
  缓冲区中开始读入缓冲区的起点。

答案 1 :(得分:0)

我认为您需要仔细阅读400字节二进制文件头记录的定义:它们被定义为双字节或四字节,两个补码整数。如3201-3204,这是四字节,3213-3214,这是两个字节。除此之外,segy文件是IBM的大端数据。我认为你需要在Windows操作系统上将big-endian转换为little-endian。

答案 2 :(得分: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]);
    }