Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
8 / 6 / 2
Регистрация: 03.05.2016
Сообщений: 242

Чтение бинарного файла с данными

13.04.2022, 14:43. Показов 3764. Ответов 10
Метки c# (Все метки)

Студворк — интернет-сервис помощи студентам
Коллеги и уважаемые форумчане, добрый день! Достаточно сложная зада возникла на данный момент. Расскажу вкратце в чем состоит проблема: имеется бинарный файл (достаточно большой по размеру), суть в том, что в нем хранится запись данных с датчика (3 канала, - 3 сигнала (ток, напряжение и значения амплитуды виброактического сигнала). Есть определенная структура файла - как записаны данные, т.е. есть шапка файла, которая содержит информацию о количесвте каналов, частоте дискретизации и значений величины для каждого канала:
Структура файла

Сам бинарный файл:
Файл с исходными данными


Попытка чтения данных из бинарного файла на C# и запись виде csv файла:
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
using System.Text;
using System.IO;
 
internal class Program
{
    static void Main()
    {
        using (FileStream inputFS = File.OpenRead("data.bin"))
        using (BinaryReader reader = new BinaryReader(inputFS))
        using (StreamWriter outputFS = File.CreateText("output.csv"))
        {
            int N = reader.ReadInt32(),
                points = reader.ReadInt32(),
                freq = reader.ReadInt32();
            long tact = 0;
 
            StringBuilder output = new StringBuilder(100);
            while (tact < 100)
            {
                output.Append(tact / freq);
                for (int i = 0; i < N; i++)
                    output.Append($";{reader.ReadDouble()}");
 
                outputFS.WriteLine(output.ToString());
 
                tact++;
                output.Clear();
            }
        }
    }
}
в первом столбце такт, который потом я перевожу во время записи сигнала, а затем уже я соотсветсвтенно данные стрех каналов (некотрые нулевые значения почему-то формируются как не число, а также сами значения достаточно странные, хотя примерный диапазон значений от -5 до 5 максимум, а на самом деле еще меньше в мВ (-60 до 60)).

Вот исходный файл после преобразования:
Файл с выходными данными


Может неправильно таким образом читать бинарный файл, или же проблема по формату файла и типу данных (вместо float на самом деле double)? Я буду очень признателен любой поомщи, потому что кроме самой структуры файла и всей описанной информации никаких более сведений о файле нет, при этом хранимые в нем данные необходимо извлечь..?

Буду рад любой помощии советам!
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.04.2022, 14:43
Ответы с готовыми решениями:

Чтение бинарного файла
Добрый день, подскажите как реализовать код. Имеется структура бинарного файла (не моего) нужно его прочесть. Структура: ...

Чтение бинарного файла
проблема с чтением бинарного файла. если сделать так: byte buf_data = new byte; file.Read(buf_data, 0, 10); то в таком случае...

Чтение бинарного файла по заголовкам
Здравствуйте. Файл начинается так 00 00 00 00 FF FF 95 05 34 E8 02 00 CD 67 5A 41 первые 4 байта это номер записи потом 2 байта - номер...

10
8 / 6 / 2
Регистрация: 03.05.2016
Сообщений: 242
13.04.2022, 15:01  [ТС]
*акустического сигнала
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2022, 15:07
dux99, судя по документации, 48 байтов начиная с 12-го не используются, а вы их все равно считываете. Это специально?

Цитата Сообщение от dux99 Посмотреть сообщение
C#
1
reader.ReadDouble()
В доках указано, что значение канала — 4-байтовый float, а вы считываете 8-байтовый double.
Наверное, надо поменять на ReadSingle()?

Цитата Сообщение от dux99 Посмотреть сообщение
также сами значения достаточно странные
Подозреваю, что из-за того, что вы считываете значения двух каналов в одно число.
0
8 / 6 / 2
Регистрация: 03.05.2016
Сообщений: 242
13.04.2022, 15:21  [ТС]
kolorotur,
Цитата Сообщение от kolorotur Посмотреть сообщение
судя по документации, 48 байтов начиная с 12-го не используются, а вы их все равно считываете. Это специально?
нет, это не специально, я просто думал что раз там нет чисел и пустые значения, то он и не будет их читать, а как мне тогда организовать считывание только первых 12 байт?


Цитата Сообщение от kolorotur Посмотреть сообщение
Подозреваю, что из-за того, что вы считываете значения двух каналов в одно число.
Но вроде по структуре иду, т.е. значение 1 канала, затем для второго, затем для третьего - или в коде ошибка, я вроде считываю сразу два значения? Или Вы имеете ввиду что в процессе измерения так происходит - в самой программе, где выходной файл бинарный?

Цитата Сообщение от kolorotur Посмотреть сообщение
В доках указано, что значение канала — 4-байтовый float, а вы считываете 8-байтовый double.
Наверное, надо поменять на ReadSingle()?
Да, здесь моя ошибка - надо, конечно же, использовать ReadSingle()...
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2022, 15:33
Цитата Сообщение от dux99 Посмотреть сообщение
а как мне тогда организовать считывание только первых 12 байт?
Они уже организованы, нужно только решить что делать с остальными 28-ю байтами.
Из документации не совсем понятно: их надо игнорировать, или их в файле вообще не будет и можно продолжать считывание после 12-го байта?

Так же неясен порядок байтов в файле: он прямой или обратный?
Что вы знаете о содержимом файла, если не пользоваться своим кодом для его считывания? Сколько в нем каналов и количество точек, например?
0
8 / 6 / 2
Регистрация: 03.05.2016
Сообщений: 242
13.04.2022, 15:41  [ТС]
kolorotur,
в файле 3 канала, порядок байтов - прямой, количество точек - запись примерно 3 минуты с частотой 80 кГц, значит приблизительно 14 400 000 точек...

Вот про это не сказано, что можно ли их считывать или непосредственно игнорировать - я полагаю, раз не используются, то тогда надо просто отсальные 28 байт не считывать, хотя считывал. По сути, эта вся информация, которой располагаю...
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2022, 15:47
Цитата Сообщение от dux99 Посмотреть сообщение
в файле 3 канала, порядок байтов - прямой, количество точек - запись примерно 3 минуты с частотой 80 кГц, значит приблизительно 14 400 000 точек
Первые 3 значения сходятся с вашими (только точек 144000) если их считывать в обратном порядке, а не в прямом.
В прямом порядке там будут астрономические числа (50331648 каналов).

Или значения заголовка в обратном порядке, а данные — в прямом?
Если, скажем, посмотреть на байты с 40-го по 44-й, то они выглядят так: [ D2, FF, F9, FF ].
Если их считывать как float в обратном порядке, то значение будет NaN, если в прямом, то -5.497054e+11 (-549705400000). Насколько это значение реалистично?
0
8 / 6 / 2
Регистрация: 03.05.2016
Сообщений: 242
13.04.2022, 16:10  [ТС]
kolorotur,
Не могу сказать, насколько оно реалистично, потому что возможно, что автор программы мог их делить или умножать на коэффициент определенный, хотя в системе был подключен усилитель, поэтому если положить, что коэффициент усиления 10^11 (многовато), то возможно,но многовато все равно... Про порядок байтов - так мне сказали те, кто прислали структуру файла, но значит заголовок читается в обратном порядке, а вот с данными вопрос другой - nan может всоприниматься как нуль или ошибка датчика, хотя все равно странно.

Цитата Сообщение от kolorotur Посмотреть сообщение
(только точек 144000)
Да, я опечатался, прошу прощения.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2022, 16:22
dux99, еще один момент.
Размер прикрепленного вами файла — 88704012 байтов.
Каждое значение, судя по таблице, занимает 4 байта — получается, что всего в файле 22176003 значений.
Первые 3 значения — заголовок, потому остается 22176000 значений.
Если у каждой точки 3 значения (по одному на канал), то получается, что в файле 22176000 / 3 = 7392000 точек, а не 144000, как указано в заголовке.
Если же поделить 22176000 на предполагаемое 144000, то получается, что данные для каждой точки занимают 154 байта, а не 4 * [число каналов] (12 в данном случае).

У меня где-то в подсчетах ошибка, или там несколько "сессий" сцепленно в один файл?
0
8 / 6 / 2
Регистрация: 03.05.2016
Сообщений: 242
13.04.2022, 16:29  [ТС]
kolorotur,
Нет, это одна сессия,три канала - три сигнала. Я думаю, что часть байтов - это промежуточная информация, первые 3 значения- по 4 байта каждое, значит всего 12 байт на первые три значения, далее идут неиспользуемые, а потом значения сигналов, первые три точки, а затем снова повтор - это скорее всего уже и есть сигнал.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2022, 16:40
Лучший ответ Сообщение было отмечено dux99 как решение

Решение

dux99, ну в любом случае BinaryReader читает значения только в обратном порядке, потому вам надо либо считывать их по 4 байта, переворачивать массив и конвертировать во float, либо отказаться от использования BinaryReader.

Вот тот же вариант, только значения читаются напрямую из FileStream с помощью пары вспомогательных методов.
Значения заголовка считываются в обратном порядке, значения сигналов — в прямом.

Вывод производится в консоль, в файл можно сохранить через перенаправление вывода в консоли:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string path = @"data.bin";
 
using FileStream inputFS = File.OpenRead(path);
 
int N = inputFS.ReadInt32(),
    points = inputFS.ReadInt32(),
    freq = inputFS.ReadInt32();
long tact = 0;
 
inputFS.Position += 7 * 4; // Skip 7 unused values
 
StringBuilder output = new StringBuilder(100);
while (tact < points)
{
    output.Append(1.0 * tact / freq);
    for (int i = 0; i < N; i++)
        output.Append(";").Append(inputFS.ReadSingle());
 
    tact++;
    Console.WriteLine(output);
    output.Clear();
}
Вспомогательные методы для считывания значений в разных порядках:
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.Buffers.Binary;
 
static class StreamExtensions
{
    public static void ReadBlock(this Stream stream, Span<byte> bytes)
    {
        int read = 0;
        while (read < bytes.Length)
            read += stream.Read(bytes[read..]);
    }
 
    public static int ReadInt32(this Stream stream)
    {
        Span<byte> bytes = stackalloc byte[sizeof(int)];
        stream.ReadBlock(bytes);
 
        return BinaryPrimitives.ReadInt32LittleEndian(bytes);
    }
 
    public static float ReadSingle(this Stream stream)
    {
        Span<byte> bytes = stackalloc byte[sizeof(float)];
        stream.ReadBlock(bytes);
 
        return BinaryPrimitives.ReadSingleBigEndian(bytes);
    }
}
Если 7 значений, которые "для сигналов вибрации не используются" применяются к каждой из точек, то перенесите строку inputFS.Position += 7 * 4; // Skip 7 unused values в цикл.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.04.2022, 16:40
Помогаю со студенческими работами здесь

Чтение из бинарного файла в структуру
Совсем недавно начал изучать C# и .NET до этого программировал на C++. Хотел узнать можно ли через прямое обращение к памяти считать данные...

Чтение строки из бинарного файла
Здравствуйте, столкнулся с проблемой следующего рода: читаю dat файл, все читает нормально, пока дело не доходит до ReadString. Почему-то,...

Некорректное чтение из бинарного файла
Здравствуйте У меня следующая ситуация: 1) Создаю бинарный файл using (FileStream stream = new...

Чтение и запись бинарного файла
Помогите объяснить и переделать не большую программу с VB6 , на C#. А то перечитал много книг , но все равно некоторые моменты никак не...

Чтение структуры из бинарного файла
Всем добрый день, столкнулся с проблемой чтения структур из бинарного файла, много чего нового узнал и много в чем еще не разобрался, ниже...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru