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

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

31.07.2014, 12:55. Показов 5295. Ответов 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
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
31.07.2014, 20:20
И что из таблицы нужно записывать и куда? Тут смотреть нужно в сторону BinaryReader/Writer
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
01.08.2014, 06:49  [ТС]
ViterAlex, из таблицы, в коде прописал в скобках в начале каждой строки, что нужно, и из таблицы получается только количество строк,(диапазон как бы) всё записывается в этот файл

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

Добавлено через 4 минуты
ViterAlex, начал вот так, с этим впервые сталкиваюсь, но нужно сделать
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace KonvCSVerter
{
    public struct PARS_OF_WRITE_FILE
    {
        char Code;
        char PlataName;
        char TimeString;
        
    }
    class SaveParFile
    {
        char[] code = new char[20];
        
    }
}
а про BinaryReader/Writer сейчас почитаю, может пойму что
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
01.08.2014, 14:18  [ТС]
ViterAlex, вот нашёл пример, но он не полный (на С++)
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
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <ctype.h>
#include <conio.h>
 
struct PARS_OF_WRITE_FILE
{
    char Code[20];             // 20 Ў*©в  - "2571090,1618190     "
    char PlataName[17];        // 17 Ў*©в  - **§ў**ЁҐ Ї«*вл
    char TimeString[26];       // 26 Ў*©в  - зЁб«® Ё ўаҐ¬п §*ўҐаиҐ*Ёп ўў®¤* ¤***ле
    int ChannelsMax;           // 2 Ў*©в*  - ®ЎйҐҐ зЁб«® Є***«®ў ¤«п ўлЎа***®© Ї«*вл
    int RealChannelsQuantity;  // 2 Ў*©в*  - зЁб«® ўўҐ¤Ґ**ле (*ЄвЁў*ле) Є***«®ў
    long  RealKadrsQuantity;   // 4 Ў*©в*  - зЁб«® б®Ўа***ле Є*¤а®ў ў д®а¬*⥠'int' (< 2.147.483.648)
    long  RealSamplesQuantity; // 4 Ў*©в*  - зЁб«® б®Ўа***ле ®вбзҐв®ў ў д®а¬*⥠'int' (< 2.147.483.648)
    double TotalTime;          // 8 Ў*©в   - ўаҐ¬п ўў®¤* ў cҐЄг*¤*е ў д®а¬*⥠'DOUBLE'
    float AdcRate;             // 4 Ў*©в*  - з*бв®в* Ђ–Џ ў Єѓж ў д®а¬*⥠'FLOAT'
    float InterkadrDelay;      // 4 Ў*©в*  - ¬Ґ¦Є*¤а®ў*п §*¤Ґа¦Є* ў ¬«б ў д®а¬*⥠'FLOAT'
    float ChannelRate;         // 4 Ў*©в*  - з*бв®в* бЎ®а* ¤***ле б ®¤*®Ј® Є***«* ў Єѓж ў д®а¬*⥠'FLOAT'
    unsigned char  ActiveAdcChannelArray[32];   // 1Ў*©в*32 - ¬*ббЁў, Є*¦¤л© н«Ґ¬Ґ*в
                                                            // Є®в®а®Ј® а*ўҐ* *г«о Ё«Ё Ґ¤Ё*ЁжҐ, Ґ¤Ё*Ёз*®Ґ §**зҐ*ЁҐ
                                                            // ᮮ⢥вбвўгҐв ⮬г, зв® ¤***л© ўе®¤ *ЄвЁўҐ*
    unsigned char  AdcChannelArray[32]; // 1Ў*©в*32 - ¬*ббЁў, Є*¦¤л© н«Ґ¬Ґ*в
                                                    // Є®в®а®Ј® а*ўҐ* *®¬Ґаг Є***«* Ђ–Џ ¤«п ᮮ⢥вбвўго饣® ўе®¤*
    unsigned char  AdcGainArray[32];    //1Ў*©в**32 - ¬*ббЁў, Є*¦¤л© н«Ґ¬Ґ*в Є®в®а®Ј®
                                                    // а*ўҐ* Ё*¤ҐЄбг Є®нддЁжЁҐ*вг гбЁ«Ґ*Ёп (0,1,2 Ё«Ё 3)
    unsigned char  IsSignalArray[32];   //1Ў*©в**32 - ¬*ббЁў, Є*¦¤л© н«Ґ¬Ґ*в Є®в®а®Ј®
                                                    // Є®в®а®Ј® а*ўҐ* *г«о Ё«Ё Ґ¤Ё*ЁжҐ, Ґ¤Ё*Ёз*®Ґ §**зҐ*ЁҐ
                                                    // ᮮ⢥вбвўгҐв ⮬г, зв® ¤***л© Є***« Ўл« §*§Ґ¬«Ґ* ** Ї«*вҐ
};
 
//------------------------------------------------------------------------
// Ћб*®ў**п Їа®Ја*¬¬*
//------------------------------------------------------------------------
int main(int n_p, char **str_p)
{
    unsigned char sourcefile[20];
    unsigned char parsfile[20];
    unsigned char targetfile[20];
    char stroka[77], *endptr;
    int DataVal;
    unsigned long i, NPoints, error;
    FILE *fpsource, *fptarget, *fpfilepars;
    PARS_OF_WRITE_FILE DataPars;
 
    puts(   " File converter from 'bin' format to 'text' for L-Graph data files.\n"
            " Copyright (c) 2000 L-Card Ltd.\n"
            " Usage: convert.exe  [filename[.dat]]\n");
 
    if(n_p != 2) { puts("\n ------- ERROR1!!!\n\n"); exit(1); }
 
    // бзЁв*Ґ¬ **§ў**ЁҐ д*©«*
    strcpy(sourcefile, str_p[n_p-1]);
    strcpy(parsfile, str_p[n_p-1]);
    strcpy(targetfile, str_p[n_p-1]);
 
    // д*©« Ёб室*ле ЎЁ**а*ле ¤***ле
    if(!(endptr=strchr(sourcefile,'.'))) strcat(sourcefile, ".dat");
    else { strlwr(endptr); if(strcmp(endptr, ".dat")) { puts("\n File extention must be '.dat'!"); exit(1); }   }
 
    // д*©« Ї*а*¬Ґва®ў д*©«* ¤***ле
    if(!(endptr=strchr(parsfile,'.'))) strcat(parsfile, ".par");
    else { *endptr=0; strcat(parsfile, ".par"); }
 
    // д*©« Є®*Ґз*ле ⥪бв®ўле ¤***ле
    if(!(endptr=strchr(targetfile,'.'))) strcat(targetfile, ".txt");
    else { *endptr=0; strcat(targetfile, ".txt"); }
 
    fpsource=fopen(sourcefile, "rb");
    if(fpsource == NULL)    { printf("\n  Can't find %s!\n", sourcefile);   exit(1); }
 
    fpfilepars=fopen(parsfile, "rb");
    if(fpfilepars == NULL)  { printf("\n  Can't find %s!\n", parsfile); exit(1); }
 
    fptarget=fopen(targetfile, "wt");
    if(fptarget == NULL)    { printf("\n  Can't open %s!\n", targetfile); exit(1); }
 
    if(sizeof(PARS_OF_WRITE_FILE) != fread(&DataPars, 1, sizeof(PARS_OF_WRITE_FILE), fpfilepars))
        { puts("\n  ------- ERROR2!!!\n\n"); exit(1); }
 
// Їа®ўҐаЄ* д*©«* *.par ??????
 
    NPoints=DataPars.RealSamplesQuantity;
    for(i=error=0; i < NPoints; i++)
    {
        fread(&DataVal, 2, 1, fpsource);
        sprintf(stroka, "%7i", DataVal);
        if(((long)(i+1))%DataPars.RealChannelsQuantity) strcat(stroka, "    ");
        else strcat(stroka, "\n");
        fputs(stroka, fptarget);
        if(!(i%100000L)) { if(kbhit()) { error=1; break; } printf(" Sample %ld from %ld\r", i, NPoints); }
    }
 
    fclose(fpsource);
    fclose(fpfilepars);
    fclose(fptarget);
 
    if(error) printf("\n\n  ------- O-O-O-P-S!!!\n");
    else printf("\n\n   ------- SUCCESS!!!\n");
 
    return 0;
}
и ещё, в прикреплённом файле, код на С , и пример файла .par, каким он должен быть при открытии
Вложения
Тип файла: doc для ПАР файла.doc (27.0 Кб, 13 просмотров)
0
871 / 721 / 304
Регистрация: 15.04.2013
Сообщений: 2,047
Записей в блоге: 5
01.08.2014, 14:42
ked,
Внутренняя структура http://docs.oracle.com/cd/E196... index.html
Как получить файл http://support.sas.com/rnd/ite... rfile.html
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
01.08.2014, 14:53  [ТС]
XRoy, это всё не то
0
871 / 721 / 304
Регистрация: 15.04.2013
Сообщений: 2,047
Записей в блоге: 5
01.08.2014, 15:12
ked,
par это архив который имеет свою структуру и использует Рида-Соломона
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
02.08.2014, 14:10  [ТС]
XRoy, у меня в проге должен сохраняться .par файл после чего его можно было открывать специальной программой( для просмотра графиков)
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
12.08.2014, 02:14
Так, попробуем вернуться к теме. Проясни понятия. Что такое сегмент, кадр и канал? Где эти данные находятся в таблице, которую мы парсим из csv?
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
12.08.2014, 07:56  [ТС]
ViterAlex, Начнём с кода на С++ , который приведён выше, чтобы не запутать тебя. С помощью этого кода из двух файлов форматов .par и .dat получают файл формата .txt, грубо говоря мне нужно сделать обратную операцию.

Кадр:
C#
1
long RealKadrs64; // 8байт, число собранных кадров в 8-байтном формате.
это диапазон строк, с csv файла,
Канал - это число столбцов, указывается 32 (чтобы можно было удобно считывать информацию в дальнейшем, )
Сегмент описал в приложенном файле...

посмотри вторую форму, Struct.cs и SaveFiles.cs
Вложения
Тип файла: rar KonvCSVerter.rar (68.6 Кб, 5 просмотров)
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
12.08.2014, 09:01
Цитата Сообщение от ked Посмотреть сообщение
Начнём с кода на С++ , который приведён выше, чтобы не запутать тебя.
Как раз С++ и запутывает. Я покумекаю
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
12.08.2014, 11:02  [ТС]
ViterAlex, вот в приложенном файле сама программка и два файла .par и .dat
запусти через консоль, создастся .txt и ты поймёшь. Мне нужно сделать другую операцию , из текстового .csv в два файла .par и .dat
Вложения
Тип файла: rar С++.rar (19.9 Кб, 7 просмотров)
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
12.08.2014, 11:18  [ТС]
Вот правильный начальный файл
Вложения
Тип файла: rar Log20140711_1754 1.rar (415.6 Кб, 6 просмотров)
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
15.08.2014, 05:02
С par-файлом более-менее понятно. Запись выполняется очень просто. Я сделал для этого класс ParFile:
Класс ParFile
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
using System;
using System.Globalization;
using System.IO;
using System.Text;
 
namespace CSVtoPARNamespace {
    /*  #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()*/
    static internal class ParFile {
        static private string filename;
 
        internal static string Filename {
            get { return ParFile.filename; }
            set { ParFile.filename = value.Substring(0, value.LastIndexOf('.')) + ".par"; }
        }
 
        static internal void SaveFile() {
            using (BinaryWriter bw = new BinaryWriter(File.Open(filename, FileMode.Create), Encoding.ASCII)) {
                bw.Write("3571090,7859525".ToCharArray());//20 байт символов.
                bw.Seek(19, SeekOrigin.Begin);//Смещение на 21 байт
 
                /*17 байт названия платы. В данном случае в строке будет 14 байт,
                 * но это корректируется последующим переходом на определённую позицию,
                 * чтобы сохранить структуру*/
                bw.Write("PlataName".ToCharArray());
                bw.Seek(37, SeekOrigin.Begin);//Смещение на 37 байт
 
                //Запись даты
                bw.Write(DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss", CultureInfo.GetCultureInfo("en-us")));
                bw.Seek(62, SeekOrigin.Begin);//Смещение на 63 байта
                //Запись общего числа каналов для выбранной платы
                bw.Write((Int16)32);
                //Запись числа введённых (активных) каналов
                bw.Write((Int16)32);
 
                /*Следующие два параметра можно не писать, а сразу перейти на 8 байт
                 *bw.Seek(8, SeekOrigin.Current). Но для лучшего понимания, что происходит
                 *запишем и их.*/
                //Устаревший параметр
                bw.Write(0xFFFF);
                //Устаревший кадр
                bw.Write(0xFFFF);
                
            }
        }
    }
}

Думаю, принцип понятен. Перед вызовом метода SaveFile нужно задать имя файла csv. Класс сам заменит расширение на par.
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
15.08.2014, 06:51  [ТС]
ViterAlex, вроде бы принцип понятен...
Цитата Сообщение от ViterAlex Посмотреть сообщение
Перед вызовом метода SaveFile нужно задать имя файла csv
как его задать ? если имя выбирается в первой форме,т.е. просто перенести ?


так, а с этим:
Цитата Сообщение от ked Посмотреть сообщение
(кол-во строк) *double TotalTime; // 8 байт – время ввода в секундах в формате ‘DOUBLE’
как это написать в код ? ( у меня хоть и написано вроде, но как то каряво, выводит всегда 9 строчку, которую не надо вообще писать и не знаю как это связать с выбранными столбцами и строками, чтобы только они записывались, а не полностью весь файл

Добавлено через 14 минут
ViterAlex, и вот с этим как дела обстоят ?
C#
1
(20)  float AdcRate; // 4 байта – частота АЦП в кГц в формате ‘FLOAT’
получается нужно записать число 20
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
17.08.2014, 07:04
Цитата Сообщение от ked Посмотреть сообщение
и вот с этим как дела обстоят ?
А в чём здесь вопрос? Как записать?
C#
1
bw.Write(20f);
Единственное, что нужно помнить, что записывать числа нужно явно указывая их тип. Например, тип WORD в C# будет int16, т.е. двухбайтовое целое
В последнем приложенном архиве был файл csv. По структуре он отличается от того, с чем работали раньше. Какой файл использовать в итоге?

Мне не понятен этот параметр:
C#
1
(кол-во строк)  double TotalTime; // 8 байт – время ввода в секундах в формате ‘DOUBLE’
Что записывать: количество строк или время ввода в секундах?

Добавлено через 6 часов 12 минут
И ещё вопрсос по параметру
C#
1
(1....32)  BYTE AdcChannelArray[32]; // 1 байт *32- массив, каждый элемент которого равен номеру канала АЦП для соответствующего входа
Я так понимаю, что в массиве могут быть числа от 1 до 32. Тогда одного байта для элемента массива мало, нужно два

Добавлено через 2 часа 35 минут
Последний вопрос снимаю. Заработался

Добавлено через 18 часов 51 минуту
В общем я тут накумекал кое-что. Вкратце расскажу. Неспроста структура par-файла представлена структурой (сорри за тавтологию). Эту структуру нужно правильно описать, чтобы затем облегчить себе жизнь при записи.
Почитав, что пишут по этому поводу, пришёл к такому результату:
Структура, описывающая заголовок 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
    /// <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 Header(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 = 1.0;
            CalibrScale = 1.0;
            CalibrOffset = 0;
            Segments = 1;
        }
    }

Для каждого элемента задан тип данных, который будет использоваться при выделении памяти под эту структуру. Запись в файл теперь выглядит таким образом:
C#
1
2
3
4
5
6
7
8
9
10
11
12
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 = "PlataName";
        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);
    }
}
что касается записи блоков, то там для меня много неясного
1
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
18.08.2014, 06:40  [ТС]
ViterAlex,
Цитата Сообщение от ViterAlex Посмотреть сообщение
Что записывать: количество строк или время ввода в секундах?
ViterAlex, да именно количество строк, т.е. допустим выбрали все, то записываются все, а если диапазон от 1 до 10 , то он и должен записываться


сколько строк кода, буду разбираться

Добавлено через 3 минуты
Цитата Сообщение от ViterAlex Посмотреть сообщение
Какой файл использовать в итоге?
сколь я у всех спрашивал, все говорят по разному, как её записать, один сказал записать потоком построчно через string один говорит ещё как-то, так же в приложенных выше кодах С++ и С по разному написано, по этому я тоже уже запутался какой использовать лучше, но думаю это практически никакой роли не играет
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
18.08.2014, 06:44  [ТС]
ViterAlex, даже сделал через потоки, но запутался с записью диапазона и со всем остальным
Вложения
Тип файла: rar KonvCSVerter - ДРУГОЙ ПРОЕКТ.rar (84.7 Кб, 8 просмотров)
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
19.08.2014, 02:13
Я не пойму, что делает этот цикл:
C#
1
2
3
4
5
6
7
8
for (int i = offset; i < end - offset + 1 ; i++)
{
    for (int k = 1; k < DT[i].Length; k++)
    {
        tmp += DT[i][k] + " \n";
    }
    bw.Write(tmp + " " + "\n");
}
Что содержится в массиве DT? Какие такие строки?
0
2 / 2 / 0
Регистрация: 10.07.2014
Сообщений: 102
19.08.2014, 11:51  [ТС]
ViterAlex, вот смотри я переделал этот цикл (только, не всё правильно)
C#
1
2
3
4
5
6
for (int i = offset; i < end; i++){ // По строкам, диапазон строк
                for (int k = 0; k < sto.Length + 1 ; k++){ // По именам столбцов
                    tmp += DT[i][sto[k]] + " ";
                }
                sw.Write(tmp + "\r\n");
            }
offset - это получается начало, end - конец , по диапазону строк, т.е. когда мы на форме выбираем диапазон строк, идёт этот цикл,
sto - это имена столбцов, т.е. когда выбираем имена в checkedlistbox'e
в массиве DT содержатся полностью все строки, которые нам нужны

Не могу избавиться от дублирования строк, т.е. допустим выбрал "Имя1" и диапазон от 1 до 3, и мне пишет в файл 309, потом 309 318, потом 309 318 319,

Добавлено через 4 часа 39 минут
ViterAlex, И в этом цикле нашёл 4 ошибки, с которыми я пока что не могу разобраться:
1) Не записывается последний столбец из выбранных;
2) Когда выбираю одно имя из checkedlistbox'а, то в файл ничего не записывается;
3) Идёт дублирование строк( описано выше);
4) Выбираю допустим Имена 1,3,5,7 , а в файл записывает 2,4,6 и так же выбираю Имена 2,4,6,8 , а в файле появляются значения имён 3,5,7

Добавлено через 40 минут
Ошибки исправил
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.08.2014, 11:51
Помогаю со студенческими работами здесь

Сохранение файла в формате 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-объект не хочу. Заметил,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru