Форум программистов, компьютерный форум, киберфорум
Наши страницы
Loafer
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Первые шаги на C#

Запись от Loafer размещена 24.01.2019 в 17:55

С недавнего времени решил изучить такой замечательный язык программирования, как C#. После C++ и мучений с системами сборки и с зависимостями C# кажется просто идеальным. Как известно, лучше всего что-то учить, применяя это на практике, решая реальные задачи.

Недавно мне понадобилась утилита для анализа звуковых файлов в формате wav. Утилита просто выводит содержимое заголовка wav-файла в стандартный поток вывода. Для разработки я также использовал NuGet-пакет CommandLineParser.Оставляю код здесь, чтобы не потерять его.

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
using CommandLine;
using System.Collections.Generic;
 
namespace WaveReader
{
    public sealed class Program
    {
        private sealed class Options
        {
            [Value(0, Required = true, HelpText = "List of input files")]
            public IEnumerable<string> FilePaths { get; set; }
        }
        public static void Main(string[] args)
        {
            List<string> waveFilePaths = new List<string>();
 
            Parser.Default.ParseArguments<Options>(args).WithParsed(option =>
            {
                foreach (string filePath in option.FilePaths)
                {
                    waveFilePaths.Add(filePath);
                }
            });
 
            WaveParser waveParser = new WaveParser(waveFilePaths);
            waveParser.Parse();
        }
    }
}
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.Collections.Generic;
using System.IO;
 
namespace WaveReader
{
    internal sealed class WaveParser
    {
        public WaveParser(List<string> waveFilePaths)
        {
            _waveFilePath = waveFilePaths;
        }
 
        public void Parse()
        {
            if (!CheckFilesExist())
            {
                return;
            }
 
            foreach (string waveFilePath in _waveFilePath)
            {
                FileStream waveFileStream = new FileStream(waveFilePath, FileMode.Open);
                BinaryReader waveFileBinaryReader = new BinaryReader(waveFileStream);
 
                try
                {
                    WaveHeader waveHeader = new WaveHeader(waveFileBinaryReader);
                    ContentPrinter(waveFilePath, waveHeader);
                    Console.ReadLine();
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception.Message);
                    return;
                }
            }
        }
 
        private bool CheckFilesExist()
        {
            if (_waveFilePath.Count != 0)
            {
                foreach (string waveFilePath in _waveFilePath)
                {
                    if (!File.Exists(waveFilePath))
                    {
                        Console.WriteLine("File \"{0}\" does not exist!", waveFilePath);
                        return false;
                    }
                }
            }
            else
            {
                Console.WriteLine("List of files is empty!");
                return false;
            }
            return true;
        }
 
        private void ContentPrinter(string waveFilePath, WaveHeader waveHeader)
        {
            Console.WriteLine("+++++");
            Console.WriteLine($"File: {waveFilePath}");
            Console.WriteLine("+++++");
            Console.WriteLine($"Header content: {waveHeader}");
            Console.WriteLine("-----");
        }
 
        readonly List<string> _waveFilePath;
    }
}
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
using System.IO;
using System.Text;
 
namespace WaveReader
{
    internal sealed class WaveHeader
    {
        public WaveHeader(BinaryReader waveBinaryReader)
        {
            _riffChunkDescriptor = new RiffChunkDescriptor
            {
                ChunkID = waveBinaryReader.ReadBytes(TEXT_SIZE),
                ChunkSize = waveBinaryReader.ReadUInt32(),
                Format = waveBinaryReader.ReadBytes(TEXT_SIZE)
            };
 
            _fmtSubChunk = new FmtSubChunk
            {
                Subchunk1ID = waveBinaryReader.ReadBytes(TEXT_SIZE),
                Subchunk1Size = waveBinaryReader.ReadUInt32(),
                AudioFormat = waveBinaryReader.ReadUInt16(),
                NumChannels = waveBinaryReader.ReadUInt16(),
                SampleRate = waveBinaryReader.ReadUInt32(),
                ByteRate = waveBinaryReader.ReadUInt32(),
                BlockAlign = waveBinaryReader.ReadUInt16(),
                BitsPerSample = waveBinaryReader.ReadUInt16()
            };
 
            _dataSubChunk = new DataSubChunk
            {
                Subchunk2ID = waveBinaryReader.ReadBytes(TEXT_SIZE),
                Subchunk2Size = waveBinaryReader.ReadUInt32()
            };
        }
 
        public override string ToString()
        {
            return $"{_riffChunkDescriptor} {_fmtSubChunk} {_dataSubChunk}";
        }
 
        internal struct RiffChunkDescriptor
        {
            public byte[] ChunkID { get; set; }
            public uint ChunkSize { get; set; }
            public byte[] Format { get; set; }
            public override string ToString()
            {
                return $"\nChunkID = {Encoding.UTF8.GetString(ChunkID)} \nChunkSize = {ChunkSize} \nFormat = {Encoding.UTF8.GetString(Format)}\n";
            }
        }
 
        internal struct FmtSubChunk
        {
            public byte[] Subchunk1ID { get; set; }
            public uint Subchunk1Size { get; set; }
            public ushort AudioFormat { get; set; }
            public ushort NumChannels { get; set; }
            public uint SampleRate { get; set; }
            public uint ByteRate { get; set; }
            public ushort BlockAlign { get; set; }
            public ushort BitsPerSample { get; set; }
            public override string ToString()
            {
                string part1 = $"\nSubchunk1ID = {Encoding.UTF8.GetString(Subchunk1ID)} \nSubchunk1Size = {Subchunk1Size} \nAudioFormat = {AudioFormat} \nNumChannels = {NumChannels}";
                string part2 = $"\nSampleRate = {SampleRate} \nByteRate = {ByteRate} \nBlockAlign = {BlockAlign} \nBitsPerSample = {BitsPerSample}\n";
                return part1 + part2;
            }
        }
 
        internal struct DataSubChunk
        {
            public byte[] Subchunk2ID { get; set; }
            public uint Subchunk2Size { get; set; }
            public override string ToString()
            {
                return $"\nSubchunk2ID = {Encoding.UTF8.GetString(Subchunk2ID)} \nSubchunk2Size = {Subchunk2Size}";
            }
        }
 
        private const int TEXT_SIZE = 4;
        private readonly RiffChunkDescriptor _riffChunkDescriptor;
        private readonly FmtSubChunk _fmtSubChunk;
        private readonly DataSubChunk _dataSubChunk;
    }
}
Размещено в C#
Просмотров 398 Комментарии 4
Всего комментариев 4
Комментарии
  1. Старый комментарий
    Аватар для _lunar_
    Цитата:
    После C++ и мучений с системами сборки и с зависимостями C# кажется просто идеальным.
    выбор языка для конкретной программы зависит от того, что вы хотите получить от этой программы.
    понятное дело если нужна форма (редактор, базы данных и прочее) то шарп здесь вне конкуренции.
    а если необходимое системное программирование, без C (а то и ассемблера) вы никуда не продвинетесь.

    так что воздерживайтесь от подобных комментариев в будущем, C++ это не мучение если правильно его применять.
    Запись от _lunar_ размещена 25.01.2019 в 09:47 _lunar_ вне форума
    Обновил(-а) _lunar_ 25.01.2019 в 09:48
  2. Старый комментарий
    Аватар для Loafer
    Цитата:
    Сообщение от _lunar_ Просмотреть комментарий
    выбор языка для конкретной программы зависит от того, что вы хотите получить от этой программы.
    понятное дело если нужна форма (редактор, базы данных и прочее) то шарп здесь вне конкуренции.
    а если необходимое системное программирование, без C (а то и ассемблера) вы никуда не продвинетесь.

    так что воздерживайтесь от подобных комментариев в будущем, C++ это не мучение если правильно его применять.
    Постараюсь.
    Запись от Loafer размещена 25.01.2019 в 12:55 Loafer вне форума
  3. Старый комментарий
    Аватар для Avazart
    Цитата:
    понятное дело если нужна форма (редактор, базы данных и прочее) то шарп здесь вне конкуренции.
    А мне не понятно, тоже самое можно сделать в С++Qt.
    Запись от Avazart размещена 26.01.2019 в 13:57 Avazart вне форума
  4. Старый комментарий
    Аватар для _lunar_
    Цитата:
    Сообщение от Avazart Просмотреть комментарий
    А мне не понятно, тоже самое можно сделать в С++Qt.
    Бессмысленную полемику что круче яйца всмятку или в крутую студия или куте пожалуй пропущу..
    Запись от _lunar_ размещена 27.01.2019 в 00:18 _lunar_ вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.