Using system io c что это
Перейти к содержимому

Using system io c что это

  • автор:

Using system io c что это

Подобно паре Directory/DirectoryInfo для работы с файлами предназначена пара классов File и FileInfo . С их помощью мы можем создавать, удалять, перемещать файлы, получать их свойства и многое другое.

FileInfo

Некоторые полезные методы и свойства класса FileInfo :

  • CopyTo(path) : копирует файл в новое место по указанному пути path
  • Create() : создает файл
  • Delete() : удаляет файл
  • MoveTo(destFileName) : перемещает файл в новое место
  • Свойство Directory : получает родительский каталог в виде объекта DirectoryInfo
  • Свойство DirectoryName : получает полный путь к родительскому каталогу
  • Свойство Exists : указывает, существует ли файл
  • Свойство Length : получает размер файла
  • Свойство Extension : получает расширение файла
  • Свойство Name : получает имя файла
  • Свойство FullName : получает полное имя файла

Для создания объекта FileInfo применяется конструктор, который получает в качестве параметра путь к файлу:

FileInfo fileInf = new FileInfo(@"C:\app\content.txt");

File

Класс File реализует похожую функциональность с помощью статических методов:

  • Copy() : копирует файл в новое место
  • Create() : создает файл
  • Delete() : удаляет файл
  • Move : перемещает файл в новое место
  • Exists(file) : определяет, существует ли файл

Пути к файлам

Для работы с файлами можно применять как абсолютные, так и относительные пути:

// абсолютные пути string path1 = @"C:\Users\eugene\Documents\content.txt"; // для Windows string path2 = "C:\\Users\\eugene\\Documents\\content.txt"; // для Windows string path3 = "/Users/eugene/Documents/content.txt"; // для MacOS/Linux // относительные пути string path4 = "MyDir\\content.txt"; // для Windows string path5 = "MyDir/content.txt"; // для MacOS/Linux

Получение информации о файле

string path = @"C:\Users\eugene\Documents\content.txt"; // string path = "/Users/eugene/Documents/content.txt"; // для MacOS/Linux FileInfo fileInfo = new FileInfo(path); if (fileInfo.Exists) < Console.WriteLine($"Имя файла: "); Console.WriteLine($"Время создания: "); Console.WriteLine($"Размер: "); >

Удаление файла

string path = @"C:\app\content.txt"; FileInfo fileInf = new FileInfo(path); if (fileInf.Exists) < fileInf.Delete(); // альтернатива с помощью класса File // File.Delete(path); >

Перемещение файла

string path = @"C:\OldDir\content.txt"; string newPath = @"C:\NewDir\index.txt"; FileInfo fileInf = new FileInfo(path); if (fileInf.Exists) < fileInf.MoveTo(newPath); // альтернатива с помощью класса File // File.Move(path, newPath); >

Если файл по новому пути уже существует, то с помощью дополнительного параметра можно указать, надо ли перезаписать файл (при значении true файл перезаписывается)

string path = @"C:\OldDir\content.txt"; string newPath = @"C:\NewDir\index.txt"; FileInfo fileInf = new FileInfo(path); if (fileInf.Exists) < fileInf.MoveTo(newPath, true); // альтернатива с помощью класса File // File.Move(path, newPath, true); >

Копирование файла

string path = @"C:\OldDir\content.txt"; string newPath = @"C:\NewDir\index2.txt"; FileInfo fileInf = new FileInfo(path); if (fileInf.Exists) < fileInf.CopyTo(newPath, true); // альтернатива с помощью класса File // File.Copy(path, newPath, true); >

Метод CopyTo класса FileInfo принимает два параметра: путь, по которому файл будет копироваться, и булевое значение, которое указывает, надо ли при копировании перезаписывать файл (если true , как в случае выше, файл при копировании перезаписывается). Если же в качестве последнего параметра передать значение false , то если такой файл уже существует, приложение выдаст ошибку.

Метод Copy класса File принимает три параметра: путь к исходному файлу, путь, по которому файл будет копироваться, и булевое значение, указывающее, будет ли файл перезаписываться.

Чтение и запись файлов

В дополнение к вышерассмотренным методам класс File также предоставляет ряд методов для чтения-записи текстовых и бинарных файлов:

  • AppendAllLines(String, IEnumerable) / AppendAllLinesAsync(String, IEnumerable, CancellationToken) добавляют в файл набор строк. Если файл не существует, то он создается
  • AppendAllText(String, String) / AppendAllTextAsync(String, String, CancellationToken) добавляют в файл строку. Если файл не существует, то он создается
  • byte[] ReadAllBytes (string path) / Task ReadAllBytesAsync (string path, CancellationToken cancellationToken) считывают содержимое бинарного файла в массив байтов
  • string[] ReadAllLines (string path) / Task ReadAllLinesAsync (string path, CancellationToken cancellationToken) считывают содержимое текстового файла в массив строк
  • string ReadAllText (string path) / Task ReadAllTextAsync (string path, CancellationToken cancellationToken) считывают содержимое текстового файла в строку
  • IEnumerable ReadLines (string path) считывают содержимое текстового файла в коллекцию строк
  • void WriteAllBytes (string path, byte[] bytes) / Task WriteAllBytesAsync (string path, byte[] bytes, CancellationToken cancellationToken) записывают массив байт в бинарный файл. Если файл не существует, он создается. Если существует, то перезаписывается
  • void WriteAllLines (string path, string[] contents) / Task WriteAllLinesAsync (string path, IEnumerable contents, CancellationToken cancellationToken) записывают массив строк в текстовый файл. Если файл не существует, он создается. Если существует, то перезаписывается
  • WriteAllText (string path, string? contents) / Task WriteAllTextAsync (string path, string? contents, CancellationToken cancellationToken) записывают строку в текстовый файл. Если файл не существует, он создается. Если существует, то перезаписывается

Как видно, эти методы покрывают практически все основные сценарии — чтение и запись текстовых и бинарных файлов. Причем в зависимости от задачи можно применять как синхронные методы, так и их асинхронные аналоги.

Например, запишем и считаем обратно в строку текстовый файл:

string path = @"c:\app\content.txt"; string originalText = "Hello Metanit.com"; // запись строки await File.WriteAllTextAsync(path, originalText); // дозапись в конец файла await File.AppendAllTextAsync(path, "\nHello work"); // чтение файла string fileText = await File.ReadAllTextAsync(path); Console.WriteLine(fileText);
Hello Metanit.com Hello work

Стоит отметить, что при добавлении текста я добавил в строку последовательность «\n», которая выполняет перевод на следующую строку. Благодаря этому добавляемый текст располагается в файле на новой строке.

Если мы хотим, что в файле изначально шло добавление на новую строку, то для записи стоит использовать метод WriteAllLines/ WriteAllLinesAsync , а для добавления — AppendAllLines / AppendAllLinesAsync

await File.WriteAllLinesAsync(path, new[] < "Hello Metanit.com", "Hello work" >);

Аналогично при чтении файла если мы хотим каждую строку файла считать отдельно, то вместо ReadAllText / ReadAllTextAsync применяется ReadAllLines / ReadAllLinesAsync .

Кодировка

В качестве дополнительного параметра методы чтения-записи текстовых файлов позволяют установить кодировку в виде объекта System.Text.Encoding :

using System.Text; string path = "/Users/eugene/Documents/app/content.txt"; string originalText = "Привет Metanit.com"; // запись строки await File.WriteAllTextAsync(path, originalText, Encoding.Unicode); // дозапись в конец файла await File.AppendAllTextAsync(path, "\nПривет мир", Encoding.Unicode); // чтение файла string fileText = await File.ReadAllTextAsync(path, Encoding.Unicode); Console.WriteLine(fileText);

Для установки кодировки при записи и чтении здесь применяется встроенное значение Encoding.Unicode . Также можно указать название кодировки, единственное следует удостовериться, что текущая операционная система поддерживает выбранную кодировку:

using System.Text; string path = @"c:\app\content.txt"; string originalText = "Hello Metanit.com"; // запись строки await File.WriteAllTextAsync(path, originalText, Encoding.GetEncoding("iso-8859-1")); // дозапись в конец файла await File.AppendAllTextAsync(path, "\nHello code", Encoding.GetEncoding("iso-8859-1")); // чтение файла string fileText = await File.ReadAllTextAsync(path, Encoding.GetEncoding("iso-8859-1")); Console.WriteLine(fileText);

Введение в С# для программистов (A programmer’s Introduction to C#)

.NET Runtime имеет единое пространство имен (namespace) для всего кода программы (или метаданных). Объявление using System дает возможность ссылаться на классы, которые находятся в пространстве имен System , так что их можно использовать, не добавляя System. перед именем типа.
Пространство имен System содержит много полезных классов. Одним из них является класс Console , который используется при создании консольных приложений.

Поскольку в C# нет глобальных функций, в данном примере объявляется класс Hello, который содержит функцию static Main() , служащую начальной точкой выполнения программы. Функция Main() может быть объявлена без параметров или с параметром, который представляет собой массив строк. Поскольку Main() является точкой входа, она должна быть статической функцией. Это означает, что она не связана с конкретным объектом класса, в котором она объявлена.

Первая строка функции Main() вызывает функцию WriteLine() класса Console , которая выводит строку «Привет, Вселенная» на консоль. Цикл for перебирает параметры, полученные функцией Main() и затем выводит их на консоль с новой строки.

Пространство имен и директива using
Пространства имен в .NET Runtime используются для организации классов и других типов в единую иерархическую структуру. Правильное использование пространств имен делает классы более удобными в использовании и предотвращает конфликты с классами, написанными другими авторами.

Пространства имен можно также рассматривать как способ определить длинные имена для классов и других типов и при этом не писать каждый раз полное имя.
Пространства имен определяются с помощью ключевого слова namespace . Если нужна многоуровневая организация, пространства имен могут быть вложенными:


namespace Outer
namespace Inner
class MyClass
public static void Function() <>
>
>
>

Однако при этом приходится много печатать и выравнивать, поэтому эта конструкция может быть упрощена, если ее записать следующим образом:


namespace Outer.Inner
class MyClass
public static void Function() <>
>
>

В каждом исходном файле может быть определено столько пространств имен, сколько необходимо программисту.
Как упоминалось выше, директива using позволяет пользователю опускать названия пространств имен при использовании типа, в связи с чем использование типов становится более простым.
using — это просто ярлык, который уменьшает количество печатаемого текста, т.е. using требуется при ссылке на элементы, как показано в следующей таблице:

использование using строка кода
не используется System.Console.WriteLine(«Hello»);
using System Console.WriteLine(«Hello»);

Обратите внимание, что using не может использоваться с именем класса, чтобы затем имя класса могло быть опущено. Другими словами, строка using System.Console будет ошибочной.
Конфликты имен, возникающие между типами или пространствами имен, которые имеют одинаковое название, всегда могут быть решены путем написания полного имени типа. Имя может быть очень длинным, если класс является глубоко вложенным, поэтому существует следующий вариант использования using , который позволяет определить псевдоним для класса:


using ThatConsoleClass = System.Console;

class Hello
public static void Main()
ThatConsoleClass.WriteLine("Hello");
>
>

Чтобы код было легче воспринимать, в примерах этой книги практически не используются пространства имен, но их необходимо использовать в реальном коде.

Базовые типы данных
C# поддерживает обычный набор типов данных. Для каждого типа данных, который поддерживается C#, существует соответствующий тип .NET Common Language Runtime. Например, типу int соответствует тип System.Int32. Практически всегда можно использовать System.Int32 вместо int , но этого не рекомендуется делать, потому что в этом случае код становится более сложным для восприятия.
Основные типы данных описаны в приведенной ниже таблице. Типы времени выполнения можно найти в
пространстве имен System из .NET Common Language Runtime.

Тип Количество
байт
Тип времени выполнения Описание
byte 1 Byte Unsigned byte
sbyte 1 SByte Signed byte
short 2 Int16 Signed short
ushort 2 UInt16 Unsigned short
int 4 Int32 Signed integer
uint 4 UInt32 Unsigned int
long 8 Int64 Signed big integer
ulong 8 UInt64 Unsigned big integer
float 4 Single Floating point number
double 8 Double Double-precision floating point number
decimal 8 Decimal Fixed-precision number
string String Unicode string
char Char Unicode character
bool Boolean Boolean value

Различие между базовыми (или встроенными) типами в C# является в значительной степени искусственным, поскольку определяемые пользователем типы могут вести себя так же, как встроенные. Фактически, единственное реальное отличие встроенных типов данных от типов, определяемых пользователем, заключается в том, что существует возможность задавать константные значения (literal values) для встроенных типов.

Типы данных делятся на обычные (или простые) и ссылочные типы. Обычные типы хранятся в стеке или
встраиваются в структуру, полем которой они являются. Для ссылочных типов выделяется место в куче (heap).

И ссылочные, и обычные типы являются производными от базового класса object. В тех случаях, когда
обычный тип должен вести себя как объект, создается оболочка (wrapper), которую можно рассматривать как ссылочный объект, помещенный в кучу, и в нее копируется значение переменной обычного типа. Оболочка автоматически помечается таким образом, что система знает, какое значение она содержит. Этот процесс известен как упаковка (boxing), а обратный процесс называется распаковкой (unboxing). Упаковка происходит автоматически, для этого нужно только присвоить значение обычного типа переменной типа object. Упаковка и распаковка позволяют обрабатывать любой тип как объект. Таким образом, можно написать следующее:


using System;
class Hello
public static void Main(string[] args)
Console.WriteLine("Value is: ", 3.ToString());
>
>

Здесь целое число 3 упаковывается, и для упакованного значения вызывается функция Int32.ToString() .

Массивы в C# могут быть многомерными (multidimensional) или невыровненными (jagged). Более сложные структуры данных такие, как стек и хеш-таблица, можно найти в пространстве имен System.Collections.

Классы, структуры и интерфейсы
В C# ключевое слово class используется для объявления ссылочного (размещаемого в куче) типа, а ключевое слово struct — для объявления обычного типа. Структуры используются для облегченных (lightweight) объектов, которые должны вести себя как встроенные типы, в остальных случаях используются классы. Например, int является обычным типом, а string — ссылочным типом. Приведенная ниже схема показывает, как они работают:

Обычный и ссылочный тип

int v = 123;
string s = «Hello There»;
Рисунок 3-1. Обычные и ссылочные типы

C# и .NET Runtime не поддерживают множественное наследование для классов, но поддерживают возможность реализации множества интерфейсов.

Инструкции (statements)
Инструкции в C# похожи на инструкции C++, но имеют несколько отличий, которые помогают избегать некоторых ошибок при их использовании. Кроме того, введены несколько новых инструкций:
Инструкция foreach позволяет получить доступ ко всем элементам массива или коллекции поочередно, в порядке возрастания индексов.
Инструкция lock используется, если программа имеет два или более потоков выполнения. При этом может возникнуть ситуация, когда два потока пытаются использовать один ресурс. Для того, чтобы избежать такой ситуации, можно создать блок критического кода. В каждый момент времени доступ к этому блоку может иметь только один поток. Этот блок создается с помощью ключевого слова lock .
Инструкции checked и unchecked позволяют управлять проверкой переполнения при арифметических операциях и преобразованиях. Если часть кода помечена как checked , то в случае переполнения генерируется исключение. При использовании unchecked в случае переполнения результат просто усекается.

Перечисления (enums)
Перечисления используются для объявления набора связанных по смыслу констант (например, набора цветов, в которые может быть окрашен контрол) ясным и безопасным способом. Например:

enum Colors red, 
green,
blue
>

Делегаты и события (delegates and events)
Делегаты представляют собой безопасную, объектно-ориентированную реализацию указателя на функцию. Делегаты используются в ситуациях, когда какой-либо компонент должен обратиться к компоненту, который его использует. Наиболее эффективно делегаты используются в качестве основания для событий , при этом делегат легко регистрируется как обработчик события.

Свойства и индексаторы
C# поддерживает свойства и индексаторы , которые помогают отделить интерфейс объекта от его реализации. Вместо того, чтобы разрешить пользователю обратиться к полю или массиву напрямую, свойство или индексатор позволяют определить блок операторов, реализующих доступ, если использование поля или массива разрешено. Приведем простой пример:


using System;
class Circle public int X get return(x);
>
set x = value;
//draw the object here.
>
>
int x;
>

class Test public static void Main() Circle c = new Circle();
c.X = 35;
>
>

В этом примере get и set являются средствами доступа и вызываются, когда происходит обращение к свойству Х.

Атрибуты
Атрибуты используются в C# и .NET Frameworks для передачи описательной информации от автора кода другим частям кода, если они заинтересованы в этой информации. Атрибуты можно использовать, чтобы определить, какое поле объекта должно быть сериализовано, как отображать класс в браузере для классов и др.

Атрибуты записываются в квадратных скобках. Например, атрибут может выглядеть так:
[CodeReview(«12/31/1999″, Comment=»Well done»)].

Информация, содержащаяся в атрибуте, восстанавливается во время выполнения с помощью процесса, называемого рефлексией (reflection). Можно легко писать новые атрибуты, применять их к элементам кода (к классам, полям, параметрам и т.д.) и восстанавливать их с помощью рефлексии.

Как обработать исключение — System.PlatformNotSupportedException: «System.IO.Ports is currently only supported on Windows.»?

Хочу в консольном приложении подключиться к ПЛК через переходник RS485/USB. Не доходя до прочего кода (параметры подключения, чтение и запись данных ПЛК), получаю указанное выше исключение:

using System.IO.Ports; List allports = SerialPort.GetPortNames().ToList(); // здесь выходит исключение string port = allports.Last(); SerialPort serial = new SerialPort(port); // если убрать предыдущие две строчки, заменив port на "COM4", то тогда здесь выйдет исключение 

Основной вопрос: как правильно обработать это исключение (отключать не хочется) ? Изменял параметры проекта с дефолтных на: Целевая платформа — Windows; Целевая версия ОС — 7; Целевая платформа — х64. Не помогло, вернул на прежние (нет целевой платформы и Any CPU), чтобы потом под Linux опробовать работу приложения. Дополнительный вопрос: на Windows строка string port = allports.Last(); выдаёт мне через C#Interactive (тут это исключение не выходит и код работает) результат «COM4» . Такое наименование, как я понимаю, свойственно только для Windows. Будет ли указанный код работать на Linux, чтобы сделать мне new SerialPort(port); с результатом вроде «/dev/ttyUSB0» ?

Пространство имен System.IO

Пространство имен System.IO в .NET — это область библиотек базовых классов, посвященная службам файлового ввода-вывода, а также ввода-вывода из памяти. Подобно любому пространству имен, в System.IO определен набор классов, интерфейсов, перечислений, структур и делегатов, большинство из которых находятся в mscorlib.dll. В дополнение к типам, содержащимся внутри mscorlib.dll, в сборке System.dll определены дополнительные члены пространства имен System.IO. Обратите внимание, что все проекты Visual Studio 2010 автоматически устанавливают ссылки на обе сборки.

Многие типы из пространства имен System.IO сосредоточены на программных манипуляциях физическими каталогами и файлами. Дополнительные типы предоставляют поддержку чтения и записи данных в строковые буферы, а также области памяти. Ниже кратко описаны основные (неабстрактные) классы, которые дают понятие о функциональности System.IO:

BinaryReader, BinaryWriter

Эти классы позволяют сохранять и извлекать элементарные типы данных (целочисленные, булевские, строковые и т.п.) в двоичном виде

BufferedStream

Этот класс предоставляет временное хранилище для потока байтов, которые могут затем быть перенесены в постоянные хранилища

Directory, DirectoryInfo

Эти классы используются для манипуляций структурой каталогов машины. Тип Directory представляет функциональность, используя статические члены. Тип DirectoryInfo обеспечивает аналогичную функциональность через действительную объектную ссылку

DriveInfo

Этот класс предоставляет детальную информацию относительно дисковых устройств, используемых данной машиной

File, FileInfo

Эти классы служат для манипуляций множеством файлов данной машины. Тип File представляет функциональность через статические члены. Тип FileInfo обеспечивает аналогичную функциональность через действительную объектную ссылку

FileStream

Этот класс обеспечивает произвольный доступ к файлу (т.е. возможности поиска) с данными, представленными в виде потока байт

FileSystemWatcher

Этот класс позволяет отслеживать модификации внешних файлов в определенном каталоге

MemoryStream

Этот класс обеспечивает произвольный доступ к данным, хранящимся в памяти, а не в физическом файле

Path

Этот класс выполняет операции над типами System.String, содержащими информацию о пути к файлу или каталогу в независимой от платформы манере

StreamWriter, StreamReader

Эти классы используются для хранения (и извлечения) текстовой информации из файла. Эти классы не поддерживают произвольного доступа к файлу

StringWriter, StringReader

Подобно классам StreamWriter/StreamReader, эти классы также работают с текстовой информацией. Однако лежащим в основе хранилищем является строковый буфер, а не физический файл

В дополнение к этим конкретным типам классов в System.IO определено несколько перечислений, а также набор абстрактных классов (т.е. Stream, TextReader и TextWriter), которые определяют разделяемый полиморфный интерфейс для всех наследников.

Как не трудно было заметить в приведенном выше списке, для представления файлов и папок используются по два класса. Какой из них применять — во многом зависит от того, сколько раз требуется получить доступ к данной папке или файлу.

  • Классы Directory и File содержат только статические методы, а их экземпляры никогда не создаются. Для их использования нужно просто предоставить путь к интересующему объекту файловой системы при каждом вызове метода-члена. Если требуется выполнить только одну операцию в отношении папки или файла, то применение этих классов является наиболее эффективным подходом, поскольку позволяет избегать накладных расходов, связанных с созданием экземпляров.
  • Классы DirectoryInfo и FileInfo реализуют практически те же общедоступные методы, что и Directory и File, а также некоторые общедоступные свойства и конструкторы, но поддерживают состояние, а их члены не являются статическими. Сначала понадобится создать их экземпляр, который затем ассоциировать с определенной папкой или файлом. Это означает, что применение этих классов будет более эффективным подходом, если необходимо выполнять множество операций в отношении одного и того же объекта. Дело в том, что во время создания они считывают информацию об аутентификации и прочие сведения о соответствующем объекте файловой системы и больше не нуждаются в ее повторном чтении, сколько бы методов не вызывалось для данного объекта (экземпляра класса). В отличие от этого, классы, не поддерживающие состояние, нуждаются в проверке деталей, связанных с файлом или папкой, при каждом вызове какого-либо метода.

Обратите внимание на рисунке, что классы Directory и File непосредственно расширяют System.Object, в то время как DirectoryInfo и FileInfo наследуются от абстрактного класса FileSystemInfo:

Классы для работы с файлами и каталогами

Классы DirectoryInfo и FileInfo унаследовали значительную часть своего поведения от абстрактного базового класса FileSystemInfo. По большей части члены класса FileSystemInfo используются для получения общих характеристик (таких как время создания, различные атрибуты и т.д.) определенного файла или каталога. В таблице ниже перечислены некоторые основные свойства, представляющие интерес:

Свойство Назначение
Attributes Получает или устанавливает ассоциированные с текущим файлом атрибуты, которые представлены перечислением FileAttributes (доступный только для чтения, зашифрованный, скрытый или сжатый)
CreationTime Получает или устанавливает время создания текущего файла или каталога
Exists Может использоваться для определения, существует ли данный файл или каталог
Extension Извлекает расширение файла
FullName Получает полный путь к файлу или каталогу
LastAccessTime Получает или устанавливает время последнего доступа к текущему файлу или каталогу
LastWriteTime Получает или устанавливает время последней записи в текущий файл или каталог
Name Получает имя текущего файла или каталога

В классе FileSystemInfo также определен метод Delete(). Этот метод реализуется производными типами для удаления файла или каталога с жесткого диска. Кроме того, метод Refresh() может быть вызван перед получением информации об атрибутах, чтобы обеспечить актуальность состояния статистики о текущем файле или каталоге.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *