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



关于这篇文章 流读取选定的列表框项目查询

我正在读取一个 SEGY 文件

(地震数据(,通过上面的帖子,我设法读取了前 3200 个字节,这是 SEGY 文件的文本文件头。

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

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

我已经修改了我的代码以尝试读取文件并跳过前 3200 个字节,但它出现了一个拒绝访问异常,我不明白为什么,我可以很好地读取 texual 标头,所以我认为这不是真的是一个访问问题。我怀疑这就是我设置二进制读取的方式。(我发现了访问问题,我没有从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());
            }

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

来自 BinaryReader.Read 的文档:

指数
缓冲区中开始读取缓冲区的起点。

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

我不是一个真正的程序员,我弄乱了 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]);
    }

最新更新