Работа с файлами.md 8.2 KB

#c #linux #windows

LINUX

Как начать

Всего нам нужны три библиотеки:

#include <sys/types.h> 
#include <sys/stat.h> // содержит флаги режимов доступа
#include <fcntl.h> // содержит флаги для открытия фалов

Основные команды

Итого для работы с файлами три функции:

  • creat - создаёт файлы и настраивает к ним доступ
  • open - открывает файл
  • read - читает файл.
  • write - пишет в файл.
  • close - высвобождение дискриптера

Open

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

int gd = open(pathname, flags, mode);

Read

Считывание не более указанного в count количество байтов из открытого файла, ссылка на который дана в fd, и сохранение их в буфере buffer.

Возвращает количество фактически считанных байтов. Если же нечего считывать возвратит 0.

numread = read(fd, buffer, count);

Write

Запись из буффера байтов, количество которых указано в "count" в открытый файл, ссылка на который дана в fd. При вызове возвращает количество фактически записанных байтов, которое может быть меньше значения, указанного в count.

numwritten = write(fd, buffer, count);

Close

Вызывается после завершения ввода-вывода с целью высвобождения дескриптора файла gd и связанных с ним ресурсов ядра.

status = close(fd)

Значение flag

В целом их много, это просто ints. Его нельзя обернуть в что-то общее, это просто перечислять нужно.

Название Значение
O_RDONLY Открытие только чтение
O_WRONLY Открытие только запись
O_RDWR Открытие чтение/запись
O_CLOEXEC Установка флага закрытия при выполнении
O_CREAT Создание файла, если он не существует
O_DIRECTORY Отказ, если аргумент pathname указывает не на каталог
O_EXCL С флагом O_CREAT, исключительное создание файла
O_LARGEFILE Для открытия в 32-разрядных системах больших файлов
O_NOFOLLOW Запрет на разыменование символных ссылок
O_TRUNC Усечение существующего файла до нулевой длины
O_APPEND Записи добавляются в конец файла
O_ASYNC Генерация сигнала, когда возможен ввод/вывод
O_DIRECT Операции ввода-ввыода осуществляются без использовании кэша
O_NOATIME Запрет на обновление времени
O_NONBLOCK Открытие в неблокируемом режиме
O_SYNC Ведение записи в файл в синхронном режиме

Значение mode

В общем это некоторая структура как всегда, принимающая в себя несколько параметров.

mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
Name What do
S_IRUSR Читает только owner
S_IWUSR Пишет только owner
S_IRGRP Читает группа
S_IWGRP Пишет группа
S_IROTH Читают все
S_IWOTH Пишут все
S_IRWXU Чтение, запись, выполнение owner
S_IRWXG Чтение, запись, выполнение группы
S_IRWXO Чтение, запись, выполнение умеют все
mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;

Code example

Open

char *path_file = "file.txt";

open(path_file, O_RDONLY);

int open_that_file(char *path_file, mode_t mode)
{
    int fd = open(path_file, O_TRUNC | O_RDWR, mode);

    return fd;
}

Write

int fd;

char *buffer = "1.0 2.0 -3.0";

void write_into_file(int fd, char *buffer)
{
    int count = write(fd, buffer, strlen(buffer));
}

Windows

Библиотеки

#include <Windows.h>

Создание файла

Во первых можно работать с двумя кодировками:

  • ASCI
  • UNICODE

Ссылка

В случае успеха - дескриптор. В случае провала - ошибка INVALID_HANDLE_VALUE

В любом случае все одинаково:

	HANDLE my_file = CreateFile(file_path /*Путь к файлу*/,
		GENERIC_READ | GENERIC_WRITE /*запрошенный доступ для чтения и писания*/,
		FILE_SHARE_READ | FILE_SHARE_WRITE /*доступ общий к файлу*/,
		NULL /*Необязательный для защиты*/,
		OPEN_ALWAYS /*Действие по отношению к файлу. Создание нового если нет, если есть усекает*/,
		FILE_ATTRIBUTE_NORMAL /*Атрибуты и флаги. Нету атрибутов и не нужны*/, 
		NULL /*Допустимый дескриптор*/);

Помним что:

  • CreateFileA - ASCI
  • CreateFIleW - Unicode

И ещё особенность в том что путь к файлу пишется следующим образом:

wchar_t* str_w = L"..//my_file.txt"; // UNICODE
char* str_a = (char*) "..//my_file.txt";  // ASCI

Писать в файл

void write_to_file_asci(HANDLE file, char* message) {
	DWORD taken_bytes;
	if (WriteFile(file, message, sizeof(char) * strlen(message), &taken_bytes, NULL)) {
		printf_s("all right");
	}
	else {
		printf("not all right");
	}
}

void wirte_to_file_unicode(HANDLE file, wchar_t  message[]) {
	DWORD taken_bytes;
	if (WriteFile(file, message, wcslen(message) * sizeof(wchar_t),  &taken_bytes, NULL)) {
		wprintf_s(L"Запись прошла успешно");
	}
	else {
		wprintf_s(L"Что-то пошло не так");
	}
}

Читать из файла

Соответственно тоже возвращает BOOL, можно также поместить внутрь условного алгоритма, но я решил реализовать обёртку.

void read_using_asci(HANDLE file, char* message) {
	int bytes_read;
	ReadFile(file, message, 100, &bytes_read, NULL);
}

void read_uisng_unicode(HANDLE file, wchar_t* message) {	
	int bytes_read;
	ReadFile(file, message, 100, &bytes_read, NULL);
}

Material

Create