* Работа с файлове от ниско ниво (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).
Добави коментар