Перейти к основному содержимому

Консоль, CLI, коллекции и файлы

Разработчику

VB.NET, после первой программы. Синтаксис коллекций в справочнике: 711 §16.

Консольное приложение

Консоль удобна для учебных задач, утилит и фоновых скриптов без WinForms. Минимальная точка входа:

Imports System

Module Program
Sub Main(args As String())
Console.OutputEncoding = System.Text.Encoding.UTF8
Console.WriteLine("Аргументы: " & String.Join(", ", args))
Console.Write("Введите имя: ")
Dim name = Console.ReadLine()
Console.WriteLine($"Здравствуйте, {name}")
End Sub
End Module
ЗадачаAPI
Аргументы командной строкиSub Main(args As String())
Ввод строкиConsole.ReadLine()
Код выходаEnvironment.ExitCode = 1 или Return из Main в .NET 5+ top-level нет в VB — остаётся Sub Main
Пути к файлам рядом с EXEAppContext.BaseDirectory

В .NET 5+ шаблон консоли в Visual Studio может включать application framework — для простых примеров отключите «Enable application framework» в свойствах проекта, если мешает явный Sub Main.


Сборка без IDE —.NET CLI

Установленный .NET SDK позволяет создавать и запускать проекты из терминала — полезно для CI и быстрых экспериментов.

dotnet new console -lang "VB" -n DemoCli -o DemoCli
cd DemoCli
dotnet build
dotnet run -- Anton

Структура каталога:

  • DemoCli.vbproj — целевая платформа (net8.0 и т.д.), ссылки, Option Strict
  • Program.vb (или несколько .vb в одном проекте)

Публикация одного EXE (self-contained, пример):

dotnet publish -c Release -r win-x64 --self-contained true

Библиотеку классов создают так: dotnet new classlib -lang "VB". На неё ссылается консоль через <ProjectReference>.


Какую коллекцию выбрать

ТипКогда уместен
List(Of T)Упорядоченный список, доступ по индексу, частые добавления в конец
Dictionary(Of TKey, TValue)Быстрый поиск по ключу (ID, имя файла, код валюты)
HashSet(Of T)Уникальные элементы, проверка «уже есть?»
Queue(Of T) / Stack(Of T)Очередь задач, обход в ширину/глубину
LinkedList(Of T)Частые вставки/удаления в середине без сдвига массива
Массив T()Фиксированный размер, совместимость с API, который ждёт массив

Операции List(Of T):

ДействиеСинтаксис
Добавить в конецAdd(value)
ВставитьInsert(index, value)
Прочитать / заменитьlist(index), list(index) = value
Удалить по индексуRemoveAt(index)

Dictionary(Of TKey, TValue): Add, Item(key), Remove, TryGetValue.

Queue(Of T) (FIFO): Enqueue, Dequeue, Peek.

Stack(Of T) (LIFO): Push, Pop, Peek.

Imports System.Collections.Generic

Dim scores As New List(Of Integer) From {10, 20, 15}
scores.Sort()
Dim best = scores(scores.Count - 1)

Dim byId As New Dictionary(Of Integer, String)
byId(1) = "Anna"
Dim name As String = Nothing
If byId.TryGetValue(2, name) Then
Console.WriteLine(name)
Else
byId(2) = "Boris"
End If

Обход и LINQ

For Each работает с любым IEnumerable(Of T):

For Each pair In byId
Console.WriteLine($"{pair.Key}: {pair.Value}")
Next

Краткий запрос без отдельной функции:

Dim longNames = From name In byId.Values Where name.Length > 4 Select name

Собственный класс с IEnumerable(Of T), индексаторами и перегрузкой операторов — в главе 11.


Работа с файлами и каталогами

Предпочтительны классы System.IO (одинаковы для VB.NET и C#), а не устаревшие функции VB6 (FileOpen, Line Input).

Пути

Imports System.IO

Dim baseDir = AppContext.BaseDirectory
Dim dataPath = Path.Combine(baseDir, "data", "input.txt")
Directory.CreateDirectory(Path.GetDirectoryName(dataPath))

Path.Combine корректно склеивает сегменты под Windows и Linux.

Текст целиком

Подходит для небольших конфигов и логов:

File.WriteAllText(dataPath, "line1" & Environment.NewLine & "line2", Text.UTF8Encoding.UTF8)
Dim text = File.ReadAllText(dataPath, Text.UTF8Encoding.UTF8)

Потоковое чтение (большие файлы)

Using reader As New StreamReader(dataPath, Text.UTF8Encoding.UTF8)
While Not reader.EndOfStream
Dim line = reader.ReadLine()
If line IsNot Nothing AndAlso line.Length > 0 Then
Console.WriteLine(line)
End If
End While
End Using

Using гарантирует закрытие файла даже при исключении (реализация IDisposable).

Запись построчно

Using writer As New StreamWriter(dataPath, append:=False, encoding:=Text.UTF8Encoding.UTF8)
writer.WriteLine("первая строка")
writer.WriteLine("вторая строка")
End Using

Метаданные

Dim info As New FileInfo(dataPath)
If info.Exists Then
Console.WriteLine($"Размер: {info.Length} байт, изменён: {info.LastWriteTime}")
End If

Бинарные форматы (собственные заголовки, сжатие) читают через FileStream + BinaryReader / BinaryWriter; для JSON и XML в .NET обычно берут отдельные библиотеки (System.Text.Json, System.Xml.Linq) — см. справочник §18.


Типичные ошибки

СимптомПричинаЧто сделать
IOException при записиФайл открыт в другой программеЗакрыть редактор, использовать Using
Кракозябры в консолиКодировка консоли ≠ UTF-8Console.OutputEncoding, сохранять файл в UTF-8
KeyNotFoundExceptionОбращение dict(key) без проверкиTryGetValue или ContainsKey
Путь не найденОтносительный путь от «не того» каталогаAppContext.BaseDirectory или абсолютный путь

Связь с GUI и VBA

  • WinForms и WPF используют те же List(Of T) и File в фоновых задачах; долгие операции — Async/Await (см. процедуры).
  • Макросы внутри Excel по-прежнему проще на VBA; управление файлами там — Open, Write #, объект FileSystemObject.

См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).