C#读取横河WVF数据文件

横河wvf型数据,分别保存在hdr(数据信息文件)和wvf(数据文件)两个文件中。

其中HDR文件格式及参数可以参考: http://www.yokogawa.com/jp-ymi/tm/TI/TIdoc/TI700021.pdf

 

1.保存hdr中数据信息的结构体

View Code
//.hdr文件的wvf文件信息struct

public struct WVFInfo

{

    public string FileName;

    public string FormatVersion;

    public string Model;

    public WVFEndianType Endian;

    public string DataFormat;

    public int GroupNumber;

    public int TraceTotalNumber;

    public int DataOffset;

    public List<WVFGroup> Groups;

}



//wvf group struct

public struct WVFGroup

{

    public int TraceNumber;

    public int BlockNumber;



    //Traces

    public List<string> TraceName;

    public List<int> BlockSize;

    public List<double> VResolution;

    public List<double> VOffset;

    public List<WVFByteFormatType> VDataTypeByteFormat;

    public List<int> VDataTypeByteNumber;

    public List<string> VUnit;

    public List<string> VPlusOverData;

    public List<string> VMinusOverData;

    public List<double> VIllegalData;

    public List<double> VMaxData;

    public List<double> VMinData;

    public List<double> HResolution;

    public List<double> HOffset;

    public List<string> HUnit;



    //currently only support 1 block

    public List<string> Date;

    public List<string> Time;

    public List<List<double>> TValues;

    public List<List<double>> YValues;

}



//wvf文件的数据格式struct

public enum WVFByteFormatType

{

    IS = 0, //int

    IU = 1, //unsigned int

    FS = 2, //float

}



//wvf文件的数据大小端struct

public enum WVFEndianType

{

    Big = 0, //Big Endian

    Little = 1 //Little Endian

}

 

2.读取hdr时会用到的字符串操作函数

View Code
string fileparse(string keyword, string text)

{

    string value = "";

    int indexStart = text.IndexOf(keyword);





    if (indexStart < 0)

    {

        Console.WriteLine("Could not find " + keyword + " entry in the file");

    }

    else

    {

        int indexEnd = text.Substring(indexStart).IndexOf("\r\n");

        string line = text.Substring(indexStart, indexEnd).Trim();

        value = line.Replace(keyword, " ").Trim();

    }



    return value;

}



List<string> stringparse(string str)

{

    string[] args = str.Trim().Split(' ');

    List<string> list = new List<string>();



    foreach (string arg in args)

    {

        if (arg.Trim().Length != 0)

        {

            list.Add(arg);

        }

    }



    return list;

}

 

3. 读取hdr文件的函数

View Code
//read header .hdr file

void ReadHDR(string path)

{

    string content = File.ReadAllText(path);



    info.FileName = path.Substring(0, path.LastIndexOf('.'));

    info.FormatVersion = fileparse("FormatVersion", content);

    info.Model = fileparse("Model", content);

    info.DataFormat = fileparse("DataFormat", content);

    info.GroupNumber = Convert.ToInt32(fileparse("GroupNumber", content));

    info.TraceTotalNumber = Convert.ToInt32(fileparse("TraceTotalNumber", content));

    info.DataOffset = Convert.ToInt32(fileparse("DataOffset", content));

    info.Endian = (fileparse("Endian", content) == "Big") ? WVFEndianType.Big : WVFEndianType.Little;

    info.Groups = new List<WVFGroup>();



    for (int i = 0; i < Info.GroupNumber; i++)

    {

        //Group

        WVFGroup group = new WVFGroup();

        int groupIndex = content.IndexOf("$Group" + (i+1).ToString());

        string groupContent = content.Substring(groupIndex);

        group.TraceNumber = Convert.ToInt32(fileparse("TraceNumber", groupContent));

        group.BlockNumber = Convert.ToInt32(fileparse("BlockNumber", groupContent));

        



        //Traces

        group.TraceName = stringparse(fileparse("TraceName", groupContent));

        group.BlockSize = stringparse(fileparse("BlockSize", groupContent)).ConvertAll<int>(x => Convert.ToInt32(x));

        group.VResolution = stringparse(fileparse("VResolution", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));

        group.VOffset = stringparse(fileparse("VOffset", groupContent)).ConvertAll<double>(x=>Convert.ToDouble(x));

        

        List<string> vDataType = stringparse(fileparse("VDataType", groupContent));

        group.VDataTypeByteFormat = new List<WVFByteFormatType>();

        group.VDataTypeByteNumber = new List<int>();



        /*

        % VDataType

        % ISn : n-byte signed integer

        % IUn : n-byte unsigned integer

        % FSn : n-byte signed real

        % FUn : n-byte unsigned real

        % Bm : m-byte logical data

        */

        foreach (string dt in vDataType)

        {

            int num = 0;

            switch (dt[0])

            {

                case 'I':  //integer numbers

                    switch (dt[1])

                    {

                        case 'S':

                            group.VDataTypeByteNumber.Add(Convert.ToInt32(dt.Substring(2)));

                            group.VDataTypeByteFormat.Add(WVFByteFormatType.IS);

                            break;

                        case 'U':

                            group.VDataTypeByteNumber.Add(Convert.ToInt32(dt.Substring(2)));

                            group.VDataTypeByteFormat.Add(WVFByteFormatType.IU);

                            break;

                        default:

                            group.VDataTypeByteNumber.Add(0);

                            group.VDataTypeByteFormat.Add(WVFByteFormatType.IS);

                            break;

                    }

                    break;

                case 'F':   //real numbers

                    switch (dt[1])

                    {

                        case 'S':

                            group.VDataTypeByteNumber.Add(Convert.ToInt32(dt.Substring(2)));

                            group.VDataTypeByteFormat.Add(WVFByteFormatType.FS);

                            break;

                        default:

                            group.VDataTypeByteNumber.Add(0);

                            group.VDataTypeByteFormat.Add(WVFByteFormatType.FS);

                            break;

                    }

                    break;

                default:

                    group.VDataTypeByteNumber.Add(0);

                    group.VDataTypeByteFormat.Add(WVFByteFormatType.IS);

                    break;

            }



        }



        group.VUnit = stringparse(fileparse("VUnit", groupContent));

        group.VPlusOverData = stringparse(fileparse("VPlusOverData", groupContent));

        group.VMinusOverData = stringparse(fileparse("VMinusOverData", groupContent));

        group.VIllegalData = stringparse(fileparse("VIllegalData", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));

        group.VMaxData = stringparse(fileparse("VMaxData", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));

        group.VMinData = stringparse(fileparse("VMinData", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));

        group.HResolution = stringparse(fileparse("HResolution", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));

        group.HOffset = stringparse(fileparse("HOffset", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));

        group.HUnit = stringparse(fileparse("HUnit", groupContent));

        group.Date = stringparse(fileparse("Date", groupContent));

        group.Time = stringparse(fileparse("Time", groupContent));

        group.TValues = new List<List<double>>();

        group.YValues = new List<List<double>>();



        Info.Groups.Add(group);

    }



}

 

4. 读取wvf文件的函数

View Code
//read data .wvf file

void ReadWVF(int groupIndex = 0, int traceIndex = 0, int blockIndex = 0)

{

    // Offset at beginning of binary file

    int offset = Info.DataOffset;



    // first for all groups before the selected group

    for (int i = 0; i < groupIndex; i++)

    {

        // for all traces and blocks in these groups...

        for (int j = 0; j < Info.Groups[i].TraceNumber; j++)

        {

            // add the offsets of all traces...

            offset += Info.Groups[i].BlockSize[j] * Info.Groups[i].BlockNumber * Info.Groups[i].VDataTypeByteNumber[j];

        }

    }





    // File Format Trace or Block saves traces and blocks in different

    // sequences:

    // Trace : Group1,Trace1,Block1, Group1,Trace1,Block2, ..., Group1,Trace1,BlockN, ..., Group1,Trace2,Block1, ..., Group2,Trace1,Block1, ..., GroupN,TraceN,BlockN (each block for a specific waveform)

    // Block : Group1,Trace1,Block1, Group1,Trace2,Block1, ..., Group1,TraceN,Block1, ..., Group1,Trace1,Block2, ..., Group2,Trace1,Block1, ..., GroupN,TraceN,BlockN (each block for a specific time interval).

    if (Info.DataFormat == "Trace")

    {

        //trace format:

        //%... add offsets of the traces before the selected trace in the selected group

        for (int i = 0; i < traceIndex; i++)

        {

            offset += Info.Groups[groupIndex].BlockSize[i] * Info.Groups[groupIndex].BlockNumber * Info.Groups[groupIndex].VDataTypeByteNumber[i];

        }

        //... and finally add offsets of the blocks in the selected trace in the selected group before the selected block

        offset += Info.Groups[groupIndex].BlockSize[traceIndex] * blockIndex * Info.Groups[groupIndex].VDataTypeByteNumber[traceIndex]; ;

    }

    else

    {

        //block format:

        //%... add offsets of the blocks before the selected block in the selected group

        for (int i = 0; i < blockIndex; i++)

        {

            for (int j = 0; j < Info.Groups[groupIndex].TraceNumber; j++)

            {

                offset += Info.Groups[groupIndex].BlockSize[j] * Info.Groups[groupIndex].VDataTypeByteNumber[j];

            }

        }

        //... and finally add offsets of the traces in the selected block in the selected group before the selected trace

        for (int i = 0; i < traceIndex; i++)

        {

            offset += Info.Groups[groupIndex].BlockSize[i] * Info.Groups[groupIndex].VDataTypeByteNumber[i];

        }

    }

    

    fs.Seek(offset, SeekOrigin.Begin);



    //number of data points stored in the selected trace in the file

    int nop = Info.Groups[groupIndex].BlockSize[traceIndex];

    

    WVFByteFormatType byteFormat = Info.Groups[groupIndex].VDataTypeByteFormat[traceIndex];

    int byteNum = Info.Groups[groupIndex].VDataTypeByteNumber[traceIndex];

    List<double> listY = new List<double>();

    List<double> listT = new List<double>();

    

    //read data values

    for (int i = 0; i < nop; i++)

    {

        byte[] bVal = reader.ReadBytes(byteNum);

        double dVal = 0;



        switch (byteFormat)

        {

            case WVFByteFormatType.IS:

                switch (byteNum)

                {

                    case 2:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToInt16(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToInt16(bVal, 0);

                                break;

                        }

                        break;

                    case 4:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToInt32(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToInt32(bVal, 0);

                                break;

                        }

                        break;

                    case 8:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToInt64(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToInt64(bVal, 0);

                                break;

                        }

                        break;

                    default:

                        break;

                }

                break;

            case WVFByteFormatType.IU:

                switch (byteNum)

                {

                    case 2:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToUInt16(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToUInt16(bVal, 0);

                                break;

                        }

                        break;

                    case 4:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToUInt32(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToUInt32(bVal, 0);

                                break;

                        }

                        break;

                    case 8:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToUInt64(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToUInt64(bVal, 0);

                                break;

                        }

                        break;

                    default:

                        break;

                }

                break;

            case WVFByteFormatType.FS:

                switch (byteNum)

                {

                    case 4:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToSingle(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToSingle(bVal, 0);

                                break;

                        }

                        break;

                    case 8:

                        switch (Info.Endian)

                        {

                            case WVFEndianType.Big:

                                dVal = BitConverter.ToDouble(bVal.Reverse().ToArray(), 0);

                                break;

                            default:

                                dVal = BitConverter.ToDouble(bVal, 0);

                                break;

                        }

                        break;

                    default:

                        break;

                }

                break;

            default:

                break;



        }



        listY.Add(Info.Groups[groupIndex].VOffset[traceIndex] + Info.Groups[groupIndex].VResolution[traceIndex] * dVal);

        listT.Add(Info.Groups[groupIndex].HOffset[traceIndex] + Info.Groups[groupIndex].HResolution[traceIndex] * (1 + i));

    }



    Info.Groups[groupIndex].TValues.Add(listT);

    Info.Groups[groupIndex].YValues.Add(listY);



}

 

5. 读取wvf的类

View Code
public class WVFFile

{

    WVFInfo info = new WVFInfo();

    FileStream fs;

    BinaryReader reader;

    

    public WVFInfo Info

    {

        get { return info; }

        set { info = value; }

    }



    public WVFFile(string header, string file)

    {

       

        Info = new WVFInfo();

        ReadHDR(header);

        

        fs = new FileStream(file, FileMode.Open, FileAccess.Read);

        reader = new BinaryReader(fs);





        for(int i = 0; i < Info.GroupNumber; i++)

        {

            for (int j = 0; j < Info.Groups[i].TraceNumber; j++)

            {

                ReadWVF(i, j);

            }

        }



        reader.Close();

        fs.Close();

    }



}

 

你可能感兴趣的:(数据文件)