C, PHP, VB, .NET

Дневникът на Филип Петров


* Работа с файлове от ниско ниво (UNIX стил)

Публикувано на 26 октомври 2008 в раздел С/С++.

Функциите open, close, creat, unlink, read, write и lseek предоставят небуфериран достъп до данните във файловете. Това означава, че ще е нужно ние сами да се грижим за създаването на съответен буфер. Използват се предимно при UNIX -базирани операционни системи (Linux или BSD например).

1. open: Отваря файл с режим на достъп четене (0), запис (1) или четене+запис:

	int fd = open(char *path, int flags, mode_t mode);

Променливата fd се напича дескриптор на файла. Ако отварянето на файла не е възможно, то дескриптора ще получи стойност -1. Входния параметър name е символен низ, който описва пътя до файла в операционната система. Флаговете (flags) са следните:
O_RDONLY - само за четене.
O_WRONLY - само за запис.
O_CREAT - Създава файла ако той не съществува.
O_TRUNC - Изтрива съдържанието на файла.
...

Входния параметър mode определя режима на достъп. Той е валиден за UNIX операционни системи и се игнорира в DOS/WINDOWS:
S_IRUSR --- Read for owner.
S_IWUSR --- Write for owner.
S_IRGRP --- Read for group.
S_IROTH --- Read for other.
...

Следният пример демонстрира отваряне на файл:

	int fd;
	if ((fd = open("test.txt", O_RDONLY, 0)) < 0) printf("Open failed");

2. close: Затваря файл, отворен чрез open за четене и запис и освобождава дескриптора. Следният пример отваря и затваря файл:

	int fd = open("test.txt", 0);
	if (fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC,
                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH    )) < 0)
				              printf("Open failed");
	else close(fd);

Функцията close връща 0 при успешно изпълнение и -1 при грешка. Също както fclose се осигурява правилното записване на файла с всички актуализирани данни.

3. creat: Отваря нов файл за запис. Ако файла вече съществува, то изтрива всичката информация в него. Има следния синтаксис:

	int fd = creat(char *name, int mode);

Аналогията с open е очевидна. Тази функция е на практика излязла от употреба, защото е еквивалентна на open("name", O_WRONLY, 0)

4. unlink: Абсолютно аналогична на remove функция. Като входен параметър приема името на файла като символен низ и връща -1 при грешка.

5. read: Функцията за четене на информация от файл:

	read(int fd, char *buffer, int num);

Fd е файловия дескриптор. Buffer e указател към символен низ, в който се записват данните. Num е броя байтове на блока, който ще бъде прочетен (трябва да е равен или по-малък от размерността на буфера). Функцията връща 0 при успех и -1 при грешка.

6. write: Функцията за запис на информация във файл:

	write(int fd, char *buffer, int num);

Входните данни са аналогични както при read. Резултатът отново е 0 при успех и -1 при грешка.

7. lseek: Променя текущата позиция във файла:

	fseek(int fd, long offset, int mode);

Fd е файловият дескриптор, offset показва броя байтове, а mode указва типа на адресното преместване (0 - от началото, 1 - от текущата позиция или 2 - от края на файла "назад").

Следната програма е еквивалентна на програмата cp под UNIX (копира файлове):

	/*fileio.c
	* Tom Kelliher
	*
	* This program demonstrates how to do low-level file I/O in C.  This
	* program implements a simple version of Unix's cp command.  Two
	* filename are expected on the command line.  The first file is the
	* name of the file to be copied, the second is the file to be created.
	*/

	#include <sys/types.h>
	#include <sys/stat.h>
	#include <fcntl.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>

	/* Prototypes. */
	void pdie(const char *);
	void die(const char *);

	#define BUFFER_SIZE 1024   /* Size of the read/write buffer. */

	int main(int argc, char* argv[])
	{
		int rfd;   /* Read file descriptor. */
		int wfd;   /* Write file descriptor. */
		char buffer[BUFFER_SIZE];   /* Read/Write buffer. */
		char *bp;   /* Pointer into write buffer. */
		int bufferChars;   /* Number of bytes remaining to be written. */
		int writtenChars;  /* Number of bytes written on last write. */

		if (argc != 3)
		{
			printf("Two filenames expected.\n");
			exit(1);
		}

		/* Open file to be copied. */
		if ((rfd = open(argv[1], O_RDONLY, 0)) < 0)
			pdie("Open failed");

		/* Open file to be created. */
		if ((wfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC,
			S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
						pdie("Open failed");

		while (1)
		{
			/* Normal case --- some number of bytes read. */
			if ((bufferChars = read(rfd, buffer, BUFFER_SIZE)) > 0)
			{
				bp = buffer;   /* Pointer to next byte to write. */

				/*
				Since we can't guarantee that all the bytes will be written
				in a single write(), this code must be written such that
				several write()'s can possibly be called.
				*/
				while (bufferChars > 0)
				{
					if ((writtenChars = write(wfd, bp, bufferChars)) < 0)
					pdie("Write failed");

					bufferChars -= writtenChars;   /* Update. */
					bp += writtenChars;
				}
			}
			else if (bufferChars == 0)   /* EOF reached. */
				break;
			else   /* bufferChars < 0 --- read failure. */
				pdie("Read failed");
		}

		close(rfd);
		close(wfd);
		return 0;
	}

	// pdie --- Print error message, call perror, and die.
	void pdie(const char *mesg) {
		perror(mesg);
		exit(1);
	}

	// die --- Print error message and die.
	void die(const char *mesg) {
		fputs(mesg, stderr);
		fputc('\n', stderr);
		exit(1);
	}

Задача: Препишете този пример, така че да работи с компилатора на Visual Studio 6 (Console Application).

 



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

Адресът на електронната поща няма да се публикува


*