c#: как читать части файла? (Дицом)

Я хотел бы прочитать файл DICOM в C#. Я не хочу делать ничего необычного, я просто пока хотел бы знать, как читать в элементах, но сначала я действительно хотел бы знать Как прочитать заголовок, чтобы узнать, является ли допустимым файлом DICOM.

Он состоит из двоичных элементов данных. Первые 128 байт не используются (установлены на ноль), за ними следует строка "DICM". За этим следует информация заголовка, которая организована в группы.

A образец заголовка DICOM

First 128 bytes: unused DICOM format.
Followed by the characters 'D','I','C','M'
Followed by extra header information such as:

0002,0000, File Meta Elements Groups Len: 132
0002,0001, File Meta Info Version: 256
0002,0010, Transfer Syntax UID: 1.2.840.10008.1.2.1.
0008,0000, Identifying Group Length: 152
0008,0060, Modality: MR
0008,0070, Manufacturer: MRIcro

в приведенном выше примере заголовок организован в группы. Группа 0002 hex-это группа метаинформации файла, которая содержит 3 элемента: один определяет длину группы, один хранит версию файла и их хранит синтаксис передачи.

вопросы

  • как прочитать файл заголовка и проверить, является ли он файлом DICOM, проверив символы "D", "I", "C", " M " после 128 байтов преамбула?
  • как продолжить разбор файла, считывающего другие части данных?

6 ответов


что-то вроде этого должно читать файл, его основной и не обрабатывает все случаи, но это будет отправной точкой:


public void ReadFile(string filename)
{
    using (FileStream fs = File.OpenRead(filename))
    {
        fs.Seek(128, SeekOrigin.Begin);
        if (!(fs.ReadByte() != (byte)'D' ||
              fs.ReadByte() != (byte)'I' ||
              fs.ReadByte() != (byte)'C' ||
              fs.ReadByte() != (byte)'M'))
        {
            Console.WriteLine("Not a DCM");
            return;
        }
        BinaryReader reader = new BinaryReader(fs);

        ushort g;
        ushort e;
        do
        {
            g = reader.ReadUInt16();
            e = reader.ReadUInt16();

            string vr = new string(reader.ReadChars(2));
            long length;
            if (vr.Equals("AE") || vr.Equals("AS") || vr.Equals("AT")
                || vr.Equals("CS") || vr.Equals("DA") || vr.Equals("DS")
                || vr.Equals("DT") || vr.Equals("FL") || vr.Equals("FD")
                || vr.Equals("IS") || vr.Equals("LO") || vr.Equals("PN")
                || vr.Equals("SH") || vr.Equals("SL") || vr.Equals("SS")
                || vr.Equals("ST") || vr.Equals("TM") || vr.Equals("UI")
                || vr.Equals("UL") || vr.Equals("US"))
               length = reader.ReadUInt16();
            else
            {
                // Read the reserved byte
                reader.ReadUInt16();
                length = reader.ReadUInt32();
            }

            byte[] val = reader.ReadBytes((int) length);

        } while (g == 2);

        fs.Close();
    }

    return ;
}

код фактически не пытается учитывать, что синтаксис передачи закодированных данных может измениться после элементов группы 2, он также не пытается ничего делать с фактическими значениями, считанными.


быстрый поиск Google поднял три библиотеки DICOM c#:



просто некоторые pseudologic

Как прочитать файл заголовка и проверить, является ли он файлом DICOM, проверив символы "D", "I", "C", " M " после 128-байтовой преамбулы?

  • открыть как двоичный файл, используя файл.OpenRead
  • найдите положение 128 и прочитайте 4 байта в массив и сравните его значение байта[] для DICM. Вы можете использовать ASCIIEncoding.GetBytes () для этого

Как продолжить разбор файла, читая другой части данных?

  • продолжить чтение файла с помощью Read или ReadByte с помощью дескриптора объекта FileStream, который у вас есть ранее
  • используйте тот же метод, что и выше, чтобы выполнить сравнение.

Не забудьте закрыть и удалить файл.


вы также можете использовать такой.

FileStream fs = File.OpenRead(path);

byte[] data = new byte[132];
fs.Read(data, 0, data.Length);

int b0 = data[0] & 255, b1 = data[1] & 255, b2 = data[2] & 255, b3 = data[3] & 255;

if (data[128] == 68 && data[129] == 73 && data[130] == 67 && data[131] == 77)
        {
           //dicom file
        }
        else if ((b0 == 8 || b0 == 2) && b1 == 0 && b3 == 0)
        {
            //dicom file
        }

взято из EvilDicom.Помощник.Дикомредер из Зло Dicom библиотека:

 public static bool IsValidDicom(BinaryReader r)
    {
        try
        {
            //128 null bytes
            byte[] nullBytes = new byte[128];
            r.Read(nullBytes, 0, 128);
            foreach (byte b in nullBytes)
            {
                if (b != 0x00)
                {
                    //Not valid
                    Console.WriteLine("Missing 128 null bit preamble. Not a valid DICOM file!");
                    return false;
                }
            }
        }
        catch (Exception)
        {

            Console.WriteLine("Could not read 128 null bit preamble. Perhaps file is too short");
            return false;
        }

        try
        {
            //4 DICM characters
            char[] dicm = new char[4];
            r.Read(dicm, 0, 4);
            if (dicm[0] != 'D' || dicm[1] != 'I' || dicm[2] != 'C' || dicm[3] != 'M')
            {
                //Not valid
                Console.WriteLine("Missing characters D I C M in bits 128-131. Not a valid DICOM file!");
                return false;
            }
            return true;

        }
        catch (Exception)
        {

            Console.WriteLine("Could not read DICM letters in bits 128-131.");
            return false;
        }

    }