Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.88/26: Рейтинг темы: голосов - 26, средняя оценка - 4.88
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102

Сохранение файла в формате .par

31.07.2014, 12:55. Показов 5635. Ответов 49
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!! Помогите, пожалуйста, буду очень благодарен
Фактически сделал программу, (открывает .csv файл, разбирает его по столбцам в (CheckedListBox) и строкам в RadioButton(с диапазоном)) и после нажатия на кнопку, должно сохраняться в файл .par при этом иметь размер файла не более 1гб( если больше то сохранять в 2 файла) имя файла должно быть таким же как имя начального файла,
при этом формат файла .par должен иметь следующий вид (там где (-) значит без разницы какое значение)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#pragma pack(1)
struct PARS_OF_WRITE_FILE
{
(-)  char Code [20];//20 байт- «3571090,7859525»
(-)  char PlataName[17]; // 17 байт – название платы
(текущая дата)  char TimeString[26]; // 26 байт – число и время завершения ввода данных
(32)  WORD ChannelsMax; // 2 байта – общее число каналов для выбранной платы
(32)  WORD RealChannelsQuantity; // 2 байта – число введенных (активных) каналов
(-)  int RealKadrsQuantity; // 4 байта – устаревший параметр
(-)  int RealSamplesQuantity; // 4 байта – устаревший кадр
(кол-во строк)  double TotalTime; // 8 байт – время ввода в секундах в формате ‘DOUBLE’
(20)  float AdcRate; // 4 байта – частота АЦП в кГц в формате ‘FLOAT’
(-)  float InterkadrDelay; // 4 байта – межкадровая задержка в мс в формате ‘FLOAT’
(20/32)  float ChannelRate; // 4 байта – частота сбора данных с одного канала в кГц в формате ‘FLOAT’
(1)  bool ActiveAdcChannelArray[32]; // 1 байт *32 – массив , каждый элемент которого равен нулю или единице, единичное значение соответствует тому, что данный вход активен 
(1....32)  BYTE AdcChannelArray[32]; // 1 байт *32- массив, каждый элемент которого равен номеру канала АЦП для соответствующего входа 
(0)  BYTE AdcGainArray[32]; // 1 байт*32-массив, каждый элемент которого равен индексу коэффициенту  усиления(0,1,2 или 3)
(0)  BYTE IsSignalArray[32]; // 1 байт*31-массив, каждый элемент которого равен 0 или 1, единичное значение соответствует тому, что данный канал был заземлён на плате
(3)  int DataFormat; // 4 байта-формат данных, равен 3
(кол-во строк)  long long RealKadrs64; // 8 байт, число собранных кадров в 8-байтном формате 
(0)  double AdcOffset[32]; // 8 байт, коэффициенты смещения для подключенной платы АЦП( считываются из Flash памяти АЦП)
(1)  double AdcScale[32]; // 8 байт, , коэффициенты масштаба для подключенной платы АЦП( считываются из Flash памяти АЦП)
(1)  double CalibrScale[1024]; // 8 байт, пользовательские коэффициенты масштаба
(0)  double CalibrOffset[1024]; // 8 байт, пользовательские коэффициенты смещения 
(1)  int Segments; // число сегментов файла данных
};
#pragma pack()
далее записываются блоки данных переменной длины; кол-во блоков определяется значением переменной int Segments , Каждый блок включает:

C#
1
2
3
4
5
6
(кол-во строк)  long long current_segment_kadrs; // 8 байт, число кадров в текущем сегменте 
(текущее)  time_t current_segment_time; // 4 байта, время начало ввода сегмента в формате число секунд с 01.01.1900
(-)  double reserved1; // 8 байт, зарезервированы 
(-)  int type; // 4 байта, зарезервированы 
(-)  char current_segment_comment_on;  // ненулевое значение означает, что далее будет записано строка с комментарием(256 байт)  
(-)  char current_segment_comment[256];  //  комментарии (записываются только если comment_on=1)
помогите, пожалуйста, хотя бы примерно, или начало ,чтоб я мог продолжить,
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.07.2014, 12:55
Ответы с готовыми решениями:

Сохранение текстового файла с формате DOS\Windows
Добрый день. Возникла необходимость сохранять файл с формате DOS\Windows, а сохранение происходит в формате UNIX. Как осуществить...

Сохранение файла в формате txt
Как сохранить файл через SaveDialog в формате txt?

Сохранение файла в текстовом формате
Как сохранить данные из нескольких memo в формате txt чтобы данные данные из каждого memo представлялись отдельными столбцами, а то у меня...

49
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
20.08.2014, 00:39
Студворк — интернет-сервис помощи студентам
Непонятно почему ты работаешь со строковым массивом, ведь мы уже создали таблицу из файла. Есть метод, который из всей таблицы может сделать таблицу, содержащую выбранные строки и столбцы. Ну ладно.
Куда эти строки писать? После чего?
Сначала пишем структуру заголовка PARS_OF_WRITE_FILE. Затем ты написал:
Цитата Сообщение от ked Посмотреть сообщение
записываются блоки данных переменной длины; кол-во блоков определяется значением переменной int Segments
Это строки?
Но тогда как эти строки вписываются в
Цитата Сообщение от ked Посмотреть сообщение
Каждый блок включает:
C#
1
2
3
4
5
6
(кол-во строк) *long long current_segment_kadrs; // 8 байт, число кадров в текущем сегменте 
(текущее) *time_t current_segment_time; // 4 байта, время начало ввода сегмента в формате число секунд с 01.01.1900
(-) *double reserved1; // 8 байт, зарезервированы 
(-) *int type; // 4 байта, зарезервированы 
(-) *char current_segment_comment_on; *// ненулевое значение означает, что далее будет записано строка с комментарием(256 байт) *
(-) *char current_segment_comment[256]; *// *комментарии (записываются только если comment_on=1)
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
20.08.2014, 06:38  [ТС]
ViterAlex, Доброе утро, мы стали немного не то делать, я ошибся
Строки нужно будет записывать в бинарном виде во второй файл ".dat", пока что отложим это.
В файл ".par" должна записываться эта структура, так... В итоге, у нас должен получиться практически похожий файл на файл, который я сейчас приложил, открывал его в totalcommandor'e через HEX, в итоге я вообще без понятия пока что как делать. Предложили сделать так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
PARS_OF_WRITE_FILE Pars = new PARS_OF_WRITE_FILE();
            string fileName = "test_E-14-440_7R47412.par";
 
            FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
            
            fs.Write(Encoding.Default.GetBytes(Pars.Code.ToCharArray()),0,20);
            fs.Write(Encoding.Default.GetBytes(Pars.PlataName.ToCharArray()), 0, 17);
            fs.Write(Encoding.Default.GetBytes(Pars.TimeString.ToCharArray()), 0, 26);
            fs.Write(BitConverter.GetBytes(Pars.ChannelsMax), 0, 2);
            fs.Write(BitConverter.GetBytes(Pars.RealChannelsQuantity), 0, 2);
            fs.Write(BitConverter.GetBytes(Pars.RealKadrsQuantity), 0, 4);
            fs.Write(BitConverter.GetBytes(Pars.RealSamplesQuantity), 0, 4);
            fs.Write(Encoding.Default.GetBytes(Pars.TotalTime.ToCharArray()), 0, 8);
            fs.Write(BitConverter.GetBytes(Pars.AdcRate), 0, 4);
            fs.Write(BitConverter.GetBytes(Pars.InterkadrDelay), 0, 4);
            fs.Write(BitConverter.GetBytes(Pars.ChannelRate), 0, 4);
            fs.Write(BitConverter.GetBytes(Pars.ActiveAdcChannelArray), 0, 32);
            fs.Write(BitConverter.GetBytes(Pars.AdcChannelArray), 0, 32);
            fs.Write(BitConverter.GetBytes(Pars.AdcGainArray), 0, 32);
            fs.Write(BitConverter.GetBytes(Pars.IsSignalArray), 0, 32);
            fs.Write(BitConverter.GetBytes(Pars.DataFormat), 0, 4);
            fs.Write(BitConverter.GetBytes(Pars.RealKadrs64), 0, 8);
            fs.Write(BitConverter.GetBytes(Pars.AdcOffset), 0, 8);
            fs.Write(BitConverter.GetBytes(Pars.AdcScale), 0, 8 * 32);
            fs.Write(BitConverter.GetBytes(Pars.CalibrScale), 0, 8 * 1024);
            fs.Write(BitConverter.GetBytes(Pars.CalibrOffset), 0, 8 * 1024);
            fs.Close();
Но я точно не знаю, правильно ли это, и не знаю, что нужно присвоить каждому элементу, чтобы получить данный файл

int Segments; даже не рассматриваю пока что, рано
Вложения
Тип файла: rar test_0000_E-14-440_7D154531.rar (743 байт, 7 просмотров)
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
20.08.2014, 10:28
Значит, так. Я прикладываю готовый свой проект. Попробуй.
То, что предложили, имеет право на жизнь, но мой вариант проще в записи, хотя, может быть, сложнее в понимании.
В своём варианте я изначально определяю, сколько байт будет занимать каждое поле структуры при записи (см. сообщение ранее). Остаётся задать каждому полю значение, преобразовать всю структуру в байтовый массив и записать этот байтовый массив в файл. Всё это делает приложенный проект.
Запись выполняется так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
static internal void ConvertToPAR(DataTable dt) {
    using (BinaryWriter bw = new BinaryWriter(File.Open(filename, FileMode.Create), Encoding.ASCII)) {
        //Запись заголовка
        PARFileHeader header = new PARFileHeader(true);
        header.Code = "3571090,7859525";
        header.PlataName = "E440";
        header.TimeString = DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss", CultureInfo.GetCultureInfo("en-us"));
        header.TotalTime = (double)dt.Rows.Count;
        header.RealKadrs64 = (long)dt.Rows.Count;
        byte[] res = header.ToByteArray();
        bw.Write(res);
    }
}
Здесь задаются не все поля структуры, т.к. поля, имеющие постоянные значения, записываются в конструкторе, который вызывается в 4-й строке.
Конструктор имеет вид (файл Structures.cs):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public PARFileHeader(bool init = true) {
    Code = string.Empty;
    PlataName = string.Empty;
    TimeString = string.Empty;
    ChanellsMax = 0x20;
    RealChannelsQuantity = 0x20;
    RealKadrsQuantity = 0xFFFF;
    RealSamplesQuantity = 0xFFFF;
    TotalTime = 0.0;
    AdcRate = 20F;
    InterKadrDelay = 0xFFFF;
    ChannelRate = 20F / 32;
    ActiveAdcChannelArray = new bool[32] { 
        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
    };
            
    AdcChannelArray = new byte[32]{
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    AdcGainArray = new byte[32] { 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    IsSignalArray = new byte[32]{ 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    DataFormat = 3;
    RealKadrs64 = 0;
    AdcOffset = 0.0;
    AdcScale = 32;
    CalibrScale = 1024;
    CalibrOffset = 1024;
    Segments = 1;
}
Чтобы проверить правильность записи, нужно иметь оригинальный par-файл и знать значения полей, при которых он было создан. Тогда можно сравнить.
Вложения
Тип файла: zip sourceCode.zip (31.2 Кб, 4 просмотров)
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
20.08.2014, 15:04  [ТС]
ViterAlex,
Цитата Сообщение от ViterAlex Посмотреть сообщение
нужно иметь оригинальный par-файл и знать значения полей, при которых он было создан.
Файл приложенный выше(приложил ещё 1 rar'ку, там по 2 файла и par, и dat) и есть оригинальный par-файл, а вот значения полей это проблема...
Такие символы "p?" в файле как то связаны с 32 каналами, т.к. их так же 32 символа,
Вложения
Тип файла: rar файлы.rar (55.3 Кб, 6 просмотров)
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
20.08.2014, 15:10  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
хотя, может быть, сложнее в понимании.
Сейчас буду разбираться

C#
1
2
            bw.Write((Int16)32);
            bw.Seek(176, SeekOrigin.Current);
может пустые строки попробовать записать как нибудь так ?
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
20.08.2014, 15:54  [ТС]
ViterAlex, Вот скрины, может помогут, открыл файлы .par и .dat в программке, нам нужно получать точно такое же.
Вложения
Тип файла: rar Документ Microsoft Word.rar (782.7 Кб, 5 просмотров)
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
20.08.2014, 23:06
Приложенный par-файл содержит гораздо больше информации. Информация в заголовке приложенного файла такая:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Code = 3571090,7859525  
PlataName = E440
TimeString =   01-08-2014 15:25:08
ChanellsMax = 32
RealChannelsQuantity = 3
RealKadrsQuantity = 59904
RealSamplesQuantity = 179712
TotalTime = 5,9904
AdcRate = 10
InterKadrDelay = 0,0025
ChannelRate = 10
ActiveAdcChannelArray = System.Boolean[]
AdcChannelArray = System.Byte[]
AdcGainArray = System.Byte[]
IsSignalArray = System.Byte[]
DataFormat = 3
RealKadrs64 = 59904
AdcOffset = 1
AdcScale = 1
CalibrScale = 1
CalibrOffset = 1
Segments = 0
Следует заметить, что значение TimeString дополнено двумя пробелами слева до полной длины в 19 байт.
Я прочитал этот заголовок в описанную мною структуру, потом записал в другой файл и получил одинаковое содержимое до смещения 0x110. Дальше в оригинальном par-файле информации ещё на 33 кб. Что там должно быть?
Код для чтения данных из оригинального par-файла
Структура
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    /// <summary>
    /// Структура, описывающая заголовок файла PAR
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct PARFileHeader {
        /// <summary>
        /// Массив символов, 20 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Code;
        /// <summary>
        /// Название платы, 17 байт.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
        public string PlataName;
        /// <summary>
        /// Число и время завершения ввода данных. 26 байт.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 26)]
        public string TimeString;
        /// <summary>
        /// Общее число каналов для выбраной платы, 2 байта
        /// </summary>
        [MarshalAs(UnmanagedType.U2)]
        public Int16 ChanellsMax;
        /// <summary>
        /// Число введенных (активных) каналов, 2 байта
        /// </summary>
        [MarshalAs(UnmanagedType.U2)]
        public Int16 RealChannelsQuantity;
        /// <summary>
        /// Устаревший параметр, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int RealKadrsQuantity;
        /// <summary>
        /// Устаревший кадр, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int RealSamplesQuantity;
        /// <summary>
        /// Время ввода в секундах, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.R8)]
        public double TotalTime;
        /// <summary>
        /// Частота АЦП в кГц, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.R4)]
        public float AdcRate;
        /// <summary>
        /// Межкадровая задержка в мс, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.R4)]
        public float InterKadrDelay;
        /// <summary>
        /// Частота сбора данных с одного канала в кГц, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.R4)]
        public float ChannelRate;
        /// <summary>
        /// Массив , каждый элемент которого равен нулю или единице.
        /// Единичное значение соответствует активному входу, 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 32)]
        public bool[] ActiveAdcChannelArray;
        /// <summary>
        /// Массив, каждый элемент которого равен номеру канала АЦП для соответствующего входа, 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U2, SizeConst = 32)]
        public byte[] AdcChannelArray;
        /// <summary>
        /// Массив, каждый элемент которого равен индексу коэффициенту усиления(0, 1, 2 или 3), 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
        public byte[] AdcGainArray;
        /// <summary>
        /// Массив, каждый элемент которого равен 0 или 1, единичное значение соответствует тому, что данный канал был заземлён на плате, 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
        public byte[] IsSignalArray;
        /// <summary>
        /// Формат данных, равен 3, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int DataFormat;
        /// <summary>
        /// Число собранных кадров в 8-байтном формате, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.I8)]
        public long RealKadrs64;
        /// <summary>
        /// Коэффициенты смещения для подключенной платы АЦП( считываются из Flash памяти АЦП), 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.R8)]
        public double AdcOffset;
        /// <summary>
        /// Коэффициенты масштаба для подключенной платы АЦП( считываются из Flash памяти АЦП), 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.R8)]
        public double AdcScale;
        /// <summary>
        /// Пользовательские коэффициенты масштаба, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.R8)]
        public double CalibrScale;
        /// <summary>
        /// Пользовательские коэффициенты смещения, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.R8)]
        public double CalibrOffset;
        /// <summary>
        /// Число сегментов файла данных, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int Segments;
 
        public PARFileHeader(bool init = true) {
            Code = string.Empty;
            PlataName = string.Empty;
            TimeString = string.Empty;
            ChanellsMax = 0x20;
            RealChannelsQuantity = 0x20;
            RealKadrsQuantity = 0xFFFF;
            RealSamplesQuantity = 0xFFFF;
            TotalTime = 0.0;
            AdcRate = 20F;
            InterKadrDelay = 0xFFFF;
            ChannelRate = 20F / 32;
            ActiveAdcChannelArray = new bool[32] { 
        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
    };
 
            AdcChannelArray = new byte[32]{
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
            AdcGainArray = new byte[32] { 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
            IsSignalArray = new byte[32]{ 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
            DataFormat = 3;
            RealKadrs64 = 0;
            AdcOffset = 0.0;
            AdcScale = 32;
            CalibrScale = 1024;
            CalibrOffset = 1024;
            Segments = 1;
        }
        public override string ToString() {
            FieldInfo[] fi = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
            System.Text.StringBuilder sb = new System.Text.StringBuilder(), sb1 = new System.Text.StringBuilder();
            foreach (FieldInfo item in fi) {
                sb.AppendFormat("{0} = {1}", item.Name, item.GetValue(this).ToString());
                sb.AppendLine();
            }
            return sb.ToString();
        }
    }

Чтение байтового массива в структуру
C#
1
2
3
4
5
6
public static PARFileHeader ToFileHeader(byte[] ar) {
    GCHandle handle = GCHandle.Alloc(ar, GCHandleType.Pinned);
    PARFileHeader ph = (PARFileHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(PARFileHeader));
    handle.Free();
    return ph;
}
Чтение файла в структуру.
C#
1
2
3
4
5
6
7
static PARFileHeader ReadFromPar(string path) {
    using (BinaryReader br = new BinaryReader(File.OpenRead(path), Encoding.ASCII)) {
        byte[] ar = br.ReadBytes((int)br.BaseStream.Length);
        PARFileHeader ph = ToFileHeader(ar);
        return ph;
    }
}


Таким образом, я делаю вывод, что предложенный мною код записи в файл работает правильно. Осталось выяснить, что находится в файле дальше, после этого заголовка
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
21.08.2014, 09:54  [ТС]
ViterAlex,
Цитата Сообщение от ViterAlex Посмотреть сообщение
public override string ToString() {
Цитата Сообщение от ViterAlex Посмотреть сообщение
Чтение байтового массива в структуру
Цитата Сообщение от ViterAlex Посмотреть сообщение
Чтение файла в структуру.
ViterAlex, Их мне тоже нужно прописывать ? Если нужно то все в Structures.cs ?
Цитата Сообщение от ViterAlex Посмотреть сообщение
Дальше в оригинальном par-файле информации ещё на 33 кб. Что там должно быть?
Немного не понял, прочитал заголовок, это полностью всю структуру что ли ? Или только до TimeString, если до него, то дальше нужно остальные параметры записать: я узнал что примерно должно быть,
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Code = так же как и было  
// PlataName = здесь может быть любое имя платы, не только E440
// TimeString =  настоящее время
// ChanellsMax = записывается 32
// RealChannelsQuantity = записывается 32 как я понял, но по сути, данный параметр показывает сколько каналов у нас подключено, а их может быть и 2, и 3, и 25
// RealKadrsQuantity = 59904 может такое же число записать? как ты написал, но мне сказали записывать любое значение, вообще без разницы 
// RealSamplesQuantity = 179712 , так же, как с RealKadrsQuantity
// TotalTime = ну, тут должно быть время ввода в секундах, то есть сколько записывался выбранный диапазон строк
// AdcRate = записать 20
// InterKadrDelay = здесь вроде как без разницы, что записать
// ChannelRate = тоже без разницы,наверное, или записать так же 20
// ActiveAdcChannelArray = здесь массив, т.е. нужно прописать единичку 32 раза
// AdcChannelArray = массив, прописать от 1 до 32 
// AdcGainArray = прописать 0 , так же 32 раза
// IsSignalArray = так же
// DataFormat = просто прописать в файл число 3 
// RealKadrs64 = это количество считанных строк 
// AdcOffset =  прописать 0, 32 раза
// AdcScale = так же , только прописать 1
// CalibrScale = прописать единичку, 1024 раза
// CalibrOffset = так же, только 0
// Segments = число 1
Как-то так, вроде

Добавлено через 2 часа 41 минуту
ViterAlex, принципиально не записал вот эти значения
C#
1
2
3
4
AdcOffset = 1
AdcScale = 1
CalibrScale = 1
CalibrOffset = 1
т.к. они должны быть массивами, все проверил, всё ровно
а дальше в .par файле идут строки с символами "..р?...." по 8 байт, 32 значения , т.е. это либо параметр AdcOffset , либо AdcScale , после этого записывается CalibrScale или CalibrOffset посчитал 1024 , так же по 8байт, как раз, получается наверное , а после этого идут какие то символы, пока не разобрался
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
22.08.2014, 02:07
Цитата Сообщение от ked Посмотреть сообщение
они должны быть массивами, все проверил, всё ровно
а дальше в .par файле идут строки с символами "..р?...." по 8 байт, 32 значения , т.е. это либо параметр AdcOffset , либо AdcScale , после этого записывается CalibrScale или CalibrOffset посчитал 1024 , так же по 8байт
В описании этих типов не было слова "массив". А я не заметил, что объявлены они как массивы.

Но это легко исправляется в объявлении структуры и ни строчки кода для работы с этой структурой менять не нужно.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct PARFileHeader {
        /// <summary>
        /// Массив символов, 20 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Code;
        /// <summary>
        /// Название платы, 17 байт.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
        public string PlataName;
        /// <summary>
        /// Число и время завершения ввода данных. 26 байт.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 26)]
        public string TimeString;
        /// <summary>
        /// Общее число каналов для выбраной платы, 2 байта
        /// </summary>
        [MarshalAs(UnmanagedType.U2)]
        public Int16 ChanellsMax;
        /// <summary>
        /// Число введенных (активных) каналов, 2 байта
        /// </summary>
        [MarshalAs(UnmanagedType.U2)]
        public Int16 RealChannelsQuantity;
        /// <summary>
        /// Устаревший параметр, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int RealKadrsQuantity;
        /// <summary>
        /// Устаревший кадр, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int RealSamplesQuantity;
        /// <summary>
        /// Время ввода в секундах, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.R8)]
        public double TotalTime;
        /// <summary>
        /// Частота АЦП в кГц, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.R4)]
        public float AdcRate;
        /// <summary>
        /// Межкадровая задержка в мс, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.R4)]
        public float InterKadrDelay;
        /// <summary>
        /// Частота сбора данных с одного канала в кГц, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.R4)]
        public float ChannelRate;
        /// <summary>
        /// Массив , каждый элемент которого равен нулю или единице.
        /// Единичное значение соответствует активному входу, 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 32)]
        public bool[] ActiveAdcChannelArray;
        /// <summary>
        /// Массив, каждый элемент которого равен номеру канала АЦП для соответствующего входа, 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U2, SizeConst = 32)]
        public byte[] AdcChannelArray;
        /// <summary>
        /// Массив, каждый элемент которого равен индексу коэффициенту усиления(0, 1, 2 или 3), 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
        public byte[] AdcGainArray;
        /// <summary>
        /// Массив, каждый элемент которого равен 0 или 1, единичное значение соответствует тому, что данный канал был заземлён на плате, 32×1 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
        public byte[] IsSignalArray;
        /// <summary>
        /// Формат данных, равен 3, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int DataFormat;
        /// <summary>
        /// Число собранных кадров в 8-байтном формате, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.I8)]
        public long RealKadrs64;
        /// <summary>
        /// Коэффициенты смещения для подключенной платы АЦП( считываются из Flash памяти АЦП), 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 32)]
        public double[] AdcOffset;
        /// <summary>
        /// Коэффициенты масштаба для подключенной платы АЦП( считываются из Flash памяти АЦП), 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 32)]
        public double[] AdcScale;
        /// <summary>
        /// Пользовательские коэффициенты масштаба, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 1024)]
        public double[] CalibrScale;
        /// <summary>
        /// Пользовательские коэффициенты смещения, 8 байт
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 1024)]
        public double[] CalibrOffset;
        /// <summary>
        /// Число сегментов файла данных, 4 байта
        /// </summary>
        [MarshalAs(UnmanagedType.I4)]
        public int Segments;
 
        public PARFileHeader(bool init = true) {
            Code = string.Empty;
            PlataName = string.Empty;
            TimeString = string.Empty;
            ChanellsMax = 0x20;
            RealChannelsQuantity = 0x20;
            RealKadrsQuantity = 0xFFFF;
            RealSamplesQuantity = 0xFFFF;
            TotalTime = 0.0;
            AdcRate = 20F;
            InterKadrDelay = 0xFFFF;
            ChannelRate = 20F / 32;
            ActiveAdcChannelArray = new bool[32] { 
        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
    };
 
            AdcChannelArray = new byte[32]{
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
            AdcGainArray = new byte[32] { 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
            IsSignalArray = new byte[32]{ 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
            DataFormat = 3;
            RealKadrs64 = 0;
            AdcOffset = new double[32];
            AdcScale = new double[32]; 
            CalibrScale = new double[1024];
            CalibrOffset = new double [1024];
            Segments = 1;
        }
        public override string ToString() {
            FieldInfo[] fi = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (FieldInfo item in fi) {
                sb.AppendFormat("{0} = {1}", item.Name, item.GetValue(this).ToString());
                sb.AppendLine();
            }
            return sb.ToString();
        }
    }

Чтение структуры из файла и запись в другой файл показывает, что файлы идентичны до 0x42ee, потом в оригинальном файле идёт ещё информация. Какая?
Прилагаю скриншоты сравнения файлов. На первом скриншоте видно, что начала файлов совпадают (да и не только начала), также имеется сообщение о несовпадении данных. На втором скриншоте показано, где именно начинаются расхождения.
Дальше в оригинальном файле идёт какая-то информация с именами каналов, начиная с 0x51e0

Также прикладываю весь проект. Кстати, вопрос: на какой фреймворк делаем программу? Если она будет запускаться на разных машинах, то есть смысл обдумать минимальную версию фреймворка
Миниатюры
Сохранение файла в формате .par   Сохранение файла в формате .par  
Вложения
Тип файла: zip sourceCode.zip (31.6 Кб, 5 просмотров)
1
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
22.08.2014, 02:43
Я так понял у нас возникла путаница в терминах. Под заголовком я подразумевал часть par-файла, описываемую структурой. Поскольку так ты говорил изначально:
Цитата Сообщение от ked Посмотреть сообщение
далее записываются блоки данных переменной длины;
Я и понял, что сначала идёт заголовок файла, описываемый структурой, а затем что-то ещё. Но теперь вижу, что структура описывает весь файл. Ок. Учтём.
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
22.08.2014, 07:46  [ТС]
ViterAlex, как убрать вот эту строчку
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
static internal void SaveToPAR(DataTable dt) {
            //PARFileHeader header = new PARFileHeader(true);
            PARFileHeader header = ReadFromPar(@"C:\test_E-14-440_7R47412.par");   //ВОТ ЭТУ
            System.Windows.Forms.Clipboard.SetText(header.ToString());
            using (BinaryWriter bw = new BinaryWriter(File.Open(filename, FileMode.Create), Encoding.ASCII)) {
                ////Запись заголовка
                //header.Code = "3571090,7859525";
                //header.PlataName = "E440";
                //header.TimeString = DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss", CultureInfo.GetCultureInfo("en-us"));
                //header.TotalTime = (double)dt.Rows.Count;
                //header.RealKadrs64 = (long)dt.Rows.Count;
                byte[] res = header.ToByteArray();
                bw.Write(res);
не понял здесь код, как будто сравнивает файлы, а без этой строчки данные в файл не пишет, то есть пишет, но не показывает...

Цитата Сообщение от ViterAlex Посмотреть сообщение
Я и понял, что сначала идёт заголовок файла, описываемый структурой, а затем что-то ещё. Но теперь вижу, что структура описывает весь файл. Ок. Учтём.
Я тебя понял, вроде бы прикладывал файл с кодом на С , там в коде записи в файл написан цикл, по Segments'у , ну да , по идее можно сделать твоим способом, пробовать никто не запрещал

Сейчас попробовал открытие нашего .par файла и оригинального .dat файла, работает!
Так, закончим пока что с .par файлом, следующая информация в нём это по блокам и по одной программе данные, они нам не нужны (по крайней мере сейчас)

Сейчас нужно записать .dat файл, и надеюсь будет все работать вместе

Добавлено через 25 минут
ViterAlex, Файл .dat содержит последовательность собранных отсчётов (покадрово) в бинарном виде. Каждый отсчёт имеет размер short 16 бит.

итог, как мне сказали, допустим мы выбираем (грубо говоря) 3 имени каналов, сделать нужно цикл , читаем этот диапазон выбранных строк, по строчно т.е
ИМЯ1 ИМЯ2 ИМЯ3
120 123 532 ---вот такими строками
потом, разбиваем , как я понял тоже через цикл на числа и их в массив байт, может с dt таблицей все по другому, я думаю суть ясна, сейчас буду пробовать делать
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
22.08.2014, 13:13
Цитата Сообщение от ked Посмотреть сообщение
без этой строчки данные в файл не пишет, то есть пишет, но не показывает...
Эту строчку я добавил, чтобы проверить правильность записи в файл. Данные читаются из оригинального файла и записываются в новый. Чтобы записать свои данные, нужно эту строку закомментировать, а строки с 7 по 11 раскомментировать. Должно быть вот так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
/// Запись в PAR-файл
/// </summary>
/// <param name="dt">Таблица данных</param>
static internal void SaveToPAR(DataTable dt) {
    PARS_OF_WRITE_FILE header = new PARS_OF_WRITE_FILE();
    //PARS_OF_WRITE_FILE header = ReadFromPar(@"C:\Users\Viter\SkyDrive\Documents\Visual Studio 2013\Projects\SaveToPar\SaveToPar\Вспомогательные материалы\файлы (1)\test_E-14-440_7R47412.par");
    System.Windows.Forms.Clipboard.SetText(header.ToString());
    using (BinaryWriter bw = new BinaryWriter(File.Open(filename, FileMode.Create), Encoding.ASCII)) {
        //Запись заголовка
        header.Code = "3571090,7859525";
        header.PlataName = "E440";
        header.TimeString = DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss", CultureInfo.GetCultureInfo("en-us"));
        header.TotalTime = (double)dt.Rows.Count;
        header.RealKadrs64 = (long)dt.Rows.Count;
        byte[] res = header.ToByteArray();
        bw.Write(res);
 
    }
}
Структуру я немного подредактировал, ничего особенного, небольшие косметические правки + переименовал в PARS_OF_WRITE_FILE
PARS_OF_WRITE_FILE
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/// <summary>
/// Структура, описывающая заголовок файла PAR
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct PARS_OF_WRITE_FILE {
    /// <summary>
    /// Массив символов, 20 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string Code;
    /// <summary>
    /// Название платы, 17 байт.
    /// </summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
    public string PlataName;
    /// <summary>
    /// Число и время завершения ввода данных. 26 байт.
    /// </summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 26)]
    public string TimeString;
    /// <summary>
    /// Общее число каналов для выбраной платы, 2 байта
    /// </summary>
    [MarshalAs(UnmanagedType.U2)]
    public Int16 ChanellsMax;
    /// <summary>
    /// Число введенных (активных) каналов, 2 байта
    /// </summary>
    [MarshalAs(UnmanagedType.U2)]
    public Int16 RealChannelsQuantity;
    /// <summary>
    /// Устаревший параметр, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.I4)]
    public int RealKadrsQuantity;
    /// <summary>
    /// Устаревший кадр, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.I4)]
    public int RealSamplesQuantity;
    /// <summary>
    /// Время ввода в секундах, 8 байт
    /// </summary>
    [MarshalAs(UnmanagedType.R8)]
    public double TotalTime;
    /// <summary>
    /// Частота АЦП в кГц, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.R4)]
    public float AdcRate;
    /// <summary>
    /// Межкадровая задержка в мс, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.R4)]
    public float InterKadrDelay;
    /// <summary>
    /// Частота сбора данных с одного канала в кГц, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.R4)]
    public float ChannelRate;
    /// <summary>
    /// Массив , каждый элемент которого равен нулю или единице.
    /// Единичное значение соответствует активному входу, 32×1 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 32)]
    public bool[] ActiveAdcChannelArray;
    /// <summary>
    /// Массив, каждый элемент которого равен номеру канала АЦП для соответствующего входа, 32×1 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U2, SizeConst = 32)]
    public byte[] AdcChannelArray;
    /// <summary>
    /// Массив, каждый элемент которого равен индексу коэффициенту усиления(0, 1, 2 или 3), 32×1 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
    public byte[] AdcGainArray;
    /// <summary>
    /// Массив, каждый элемент которого равен 0 или 1.
    /// Единичное значение соответствует тому, что данный канал был заземлён на плате, 32×1 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
    public byte[] IsSignalArray;
    /// <summary>
    /// Формат данных, равен 3, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.I4)]
    public int DataFormat;
    /// <summary>
    /// Число собранных кадров в 8-байтном формате, 8 байт
    /// </summary>
    [MarshalAs(UnmanagedType.I8)]
    public long RealKadrs64;
    /// <summary>
    /// Коэффициенты смещения для подключенной платы АЦП( считываются из Flash памяти АЦП).
    /// Массив 32×8 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 32)]
    public double[] AdcOffset;
    /// <summary>
    /// Коэффициенты масштаба для подключенной платы АЦП( считываются из Flash памяти АЦП).
    /// Массив 32×8 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 32)]
    public double[] AdcScale;
    /// <summary>
    /// Пользовательские коэффициенты масштаба.
    /// Массив 1024×8 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 1024)]
    public double[] CalibrScale;
    /// <summary>
    /// Пользовательские коэффициенты смещения.
    /// Массив 1024×8 байт
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8, SizeConst = 1024)]
    public double[] CalibrOffset;
    /// <summary>
    /// Число сегментов файла данных, 4 байта
    /// </summary>
    [MarshalAs(UnmanagedType.I4)]
    public int Segments;
 
    public PARS_OF_WRITE_FILE(bool init = true) {
        Code = string.Empty;
        PlataName = string.Empty;
        TimeString = string.Empty;
        ChanellsMax = 0x20;
        RealChannelsQuantity = 0x20;
        RealKadrsQuantity = 0xFFFF;
        RealSamplesQuantity = 0xFFFF;
        TotalTime = 0.0;
        AdcRate = 20F;
        InterKadrDelay = 0xFFFF;
        ChannelRate = 20F / 32;
//      ActiveAdcChannelArray = new bool[32] { 
//  true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
//  true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
//};
        ActiveAdcChannelArray = Enumerable.Repeat<bool>(true, 32).ToArray<bool>();
        //Заполнение массива числами от 1 до 32
        AdcChannelArray = Enumerable.Range(1, 32).Select<int, byte>(x => (byte)x).ToArray();
//      AdcGainArray = new byte[32] { 
//  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
//  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
//};
        AdcGainArray = Enumerable.Repeat<byte>(byte.MinValue, 32).ToArray<byte>();
//      IsSignalArray = new byte[32]{ 
//  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
//  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
//};
        IsSignalArray = Enumerable.Repeat<byte>(byte.MinValue, 32).ToArray<byte>();
        DataFormat = 3;
        RealKadrs64 = 0;
        AdcOffset = Enumerable.Repeat<double>(0.0, 32).ToArray<double>();
        AdcScale = Enumerable.Repeat<double>(1.0, 32).ToArray<double>();
        CalibrScale = Enumerable.Repeat<double>(1.0, 1024).ToArray<double>();
        CalibrOffset = Enumerable.Repeat<double>(0.0, 1024).ToArray<double>();
        Segments = 1;
    }
    public override string ToString() {
        FieldInfo[] fi = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
        //string arValues = string.Empty;
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        foreach (FieldInfo item in fi) {
            if (item.GetType().IsArray) {
                //arValues = ArrayToString<item.GetType()>(item);
            }
            sb.AppendFormat("{0} = {1}", item.Name, item.GetValue(this).ToString());
            sb.AppendLine();
        }
        return sb.ToString();
    }
    //private string ArrayToString<T>(T[] ar) {
    //  return "{" + string.Join<T>(" ", ar) + "}";
    //}
}
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
22.08.2014, 13:30  [ТС]
ViterAlex, Где брать вот этот элемент ? Enumerable
а то сразу 12 ошибок
всё разобрался

Добавлено через 8 минут
в структуре
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public override string ToString()
        {
            FieldInfo[] fi = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
            //string arValues = string.Empty;
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (FieldInfo item in fi)
            {
                if (item.GetType().IsArray)
                {
                    //arValues = ArrayToString<item.GetType()>(item);
                }
 // здесь пишет что ссылка на объект не указывает на экземпляр объекта
                sb.AppendFormat("{0} = {1}", item.Name, item.GetValue(this).ToString());
                sb.AppendLine();
            }
            return sb.ToString();
        }
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
24.08.2014, 02:07
Цитата Сообщение от ked Посмотреть сообщение
пишет что ссылка на объект не указывает на экземпляр объекта
Моя ошибка. Перед выкладыванием, наводил порядок и при инициализации структуры вызвал не тот конструктор. В методе записи вместо строки:
C#
1
PARS_OF_WRITE_FILE header = new PARS_OF_WRITE_FILE();
Должно быть
C#
1
PARS_OF_WRITE_FILE header = new PARS_OF_WRITE_FILE(true);
Попытался реализовать запись в dat-файл. Как и в случае с par-файлом, работу с dat-файлом я вынес в отдельный статический класс. Всё то же самое, только отличается метод для записи в файл. Пока что я сделал построчное чтение с разделением строк символом новой строки \n
Запись в dat-файл выполняется после записи в par-файл. Выводится окошко с вопросом "Сохранить dat-файл?". Это сделал для контроля процесса работы. В окончательном варианте это, конечно, нужно убрать.
DatFile.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.IO;
using System.Text;
namespace ConvCSVerter {
    static internal class DatFile {
        static private string filename;
 
        internal static string Filename {
            get { return DatFile.filename; }
            set { DatFile.filename = value.Substring(0, value.LastIndexOf('.')) + ".dat"; }
        }
        static internal void WriteToDAT(System.Data.DataTable dt) {
            using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(filename), Encoding.ASCII)) {
                //object[] items;
                //Читаем построчно datatable
                foreach (System.Data.DataRow dr in dt.Rows) {
                    //TODO:Контроль размера файла при записи, чтобы не превысить 2Гб
                    //В каждой строке значения записываем в файл
                    foreach (object val in dr.ItemArray) {
                        bw.Write((Int16)val);
                    }
                    bw.Write('\n');
                }
            }
        }
    }
}
Вложения
Тип файла: zip sourceCode.zip (33.2 Кб, 4 просмотров)
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
25.08.2014, 07:19  [ТС]
ViterAlex, Всё понял, сейчас буду разбираться по .dat файлу.
Кстати, по поводу контроля размера файлов, нужно , чтобы конечные файлы не превышали размер 1Гб. Если один из файлов (.par и .dat) будет превышать размер в 1Гб, то должны создаваться следующие два файла (.par и .dat) , и имена файлов должны быть такими: "имя_часть_N" , где N - порядковый номер файла начиная с 1.

Добавлено через 42 минуты
.par файл не правильно записывается
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
25.08.2014, 12:36
Цитата Сообщение от ked Посмотреть сообщение
.par файл не правильно записывается
Что именно не так?
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
25.08.2014, 12:56  [ТС]
ViterAlex, оригинал .par файла есть ? там есть в некоторых местах "p?", так вот в нашей версии эти значки занимают больше половины файла, а после них только пустой отступ, в общем что-то не правильно записывается , приложил файлы которые записываются
Вложения
Тип файла: rar ParDat.rar (56.9 Кб, 5 просмотров)
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
28.08.2014, 06:52  [ТС]
ViterAlex, Практически сделал, осталось сделать один цикл , вчера весь вечер просидел так и не получилось, если зайдёшь то вот:
опять структура .par файла,
есть параметры:
C#
1
2
            Pars.ChannelsMax = 32; //Общее число каналов для выбранной платы, 2 байта
            Pars.RealChannelsQuantity = (short)dt.Columns.Count; //Число введенных (активных) каналов, 2 байта
параметр:
C#
1
public byte[] ActiveAdcChannelArray; // Массив, каждый элемент которого равен 0 или 1, единичное значение соответствует активному входу
так вот этот массив нужно как-то сделать через цикл, чтобы при выборе нескольких столбцов они записывались в этом массиве как единички а все остальные нулями, думаю суть понятна. Из-за этого массива программка работает не правильно.
Да, ещё и сохранение нужно сделать(которое описано выше), в интернете нет ничего подходящего, по поводу такого сохранения.
0
 Аватар для ViterAlex
8953 / 4865 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
28.08.2014, 07:33
Цитата Сообщение от ked Посмотреть сообщение
так вот этот массив нужно как-то сделать через цикл, чтобы при выборе нескольких столбцов они записывались в этом массиве как единички
Т.е. если выбраны 1, 10, 22 столбцы, то в массиве должны стоять единички в первом, десятом и двадцать втором элементе? Не три единички подряд?
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
28.08.2014, 08:18  [ТС]
ViterAlex, только что сделал, проверил, вроде всё правильно
вот так:
C#
1
2
3
4
5
6
Pars.ActiveAdcChannelArray = new byte[32];
            
            for (int i = 0; i < fot.Length; i++)
            {
                Pars.ActiveAdcChannelArray[i] = 1;
            }
осталось только с размерами файлов
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.08.2014, 08:18

Сохранение файла в формате txt
Возможно ли используя SaveDialog сохранить файл, и чтобы автоматически этому файлу приписовался тип .txt?

Сохранение файла в bmp формате
Кaк сделaть чтoбы пoсле рисoвaния метoдaми line() и circle() мoжнo былo этo сoхрaнить кaк .БМП фaил????

Сохранение в формате xml
Граждане , нид хелп :) Пилю вывод в xml формате на php из бд Получается норм в просмотре кода в браузере: &lt;?xml...

Сохранение в .exe формате
Добрый вечер! Как сохранить задачу в .exe формате?

Сохранение в формате Excel
Здравствуйте. Имеется таблица значений. Нужно данные из нее записать в файл формата XLS. Способ через COM-объект не хочу. Заметил,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru