Está en la página 1de 7

En

linux

tenemos

dos

grupos

de

funciones

para

lectura

escritura

de

ficheros.

Las

funciones open(), write(), read() y close() son de algo ms bajo nivel y especficas de linux. Dichas
funciones sern tratadas en este artculo y dejar ejemplos de cmo abrir y escribir archivos binarios. Los
que desean utilizar funciones que son estndar de C, les recomiendo que lean este artculo
Comencemos por crear un fichero. Existen dos maneras de abrir un fichero, open() y creat().
Antiguamente open() slo poda abrir ficheros que ya estaban creados por lo que era necesario
hacer una llamada a creat() para llamar a open() posteriormente. A da de hoy open() es capaz de
crear ficheros, ya que se ha aadido un nuevo parmetro en su prototipo:
int creat( const char *pathname, mode_t mode )
int open( const char *pathname, int flags )
int open( const char *pathname, int flags, mode_t mode )

Por ello, para emplear estas syscalls se suelen incluir los ficheros de cabecera:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

El funcionamiento de open() es el siguiente: al ser llamada intenta abrir el fichero indicado en la cadena
pathname con el acceso que indica el parmetro flags. Estos flags indican si queremos abrir el
fichero para lectura, para escritura, etc. La siguiente tabla especifica los valores que puede tomar este
parmetro:
Indicador

Valor

Descripcin

O_RDONLY

0000

El fichero se abre slo para lectura.

O_WRONLY

0001

El fichero se abre slo para escritura.

O_RDWR

0002

El fichero se abre para lectura y escritura.

O_RANDOM

0010

El fichero se abre para ser accedido de forma aleatoria (tpico de discos).

0020

El fichero se abre para ser accedido de forma secuencial (tpico de cintas).

0040

El fichero es de carcter temporal.

0100

El fichero deber ser creado si no exista previamente.

O_SEQUENTIA
L
O_TEMPORAR
Y
O_CREAT

O_EXCL

0200

O_NOCTTY

0400

O_TRUNC

1000

O_APPEND

2000

O_NONBLOCK 4000

Provoca que la llamada a open falle si se especifica la opcin O_CREAT y el


fichero ya exista.
Ei el fichero es un dispositivo de terminal (TTY), no se convertir en la terminal
de control de proceso (CTTY).
Fija el tamao del fichero a cero bytes.
El apuntador de escritura se situa al final del fichero, se escribirn al final los
nuevos datos.
La apertura del fichero ser no bloqueante. Es equivalente a O_NDELAY.
Fuerza a que todas las escrituras en el fichero se terminen antes de que se

O_SYNC

10000

O_ASYNC

20000 Las escrituras en el fichero pueden realizarse de manera asncrona.

O_DIRECT

40000 El acceso a disco se producir de forma directa.

O_LARGEFILE

O_DIRECTORY

O_NOFOLLOW

10000
0
20000
0

retorne de la llamada al sistema. Es equivalente a O_FSYNC.

Utilizado slo para ficheros extremadamente grandes.

El fichero debe ser un directorio.

40000 Fuerza a no seguir los enlaces simblicos. til en entornos crticos en cuanto a
0

seguridad.

Tabla: Lista de los posibles valores del argumento flags.


La lista es bastante extensa y los valores estn pensados para que sea posible concatenar o sumar
varios de ellos, es decir, hacer una OR lgica entre los diferentes valores, consiguiendo el efecto que
deseamos. As pues, podemos ver que en realidad una llamada a creat() tiene su equivalente en open(),
de esta forma:
open( pathname, O_CREAT | O_TRUNC | O_WRONLY, mode )

El argumento mode se encarga de definir los permisos dentro del Sistema de Ficheros (de la
manera de la que lo hacamos con el comando chmod). La lista completa de sus posibles
valores es esta:
Indicador Valor

Descripcin

S_IROTH 0000

Activar el bit de lectura para todo los usuarios.

S_IWOTH 0001

Activar el bit de escritura para todo los usuarios.

S_IXOTH 0002
S_IRGRP 0010

S_IRGRP 0020

S_IRGRP 0040

Activar el bit de ejecucin para todo los usuarios.


Activar el bit de lectura para todo los usuarios pertenecientes al
grupo.
Activar el bit de escritura para todo los usuarios pertenecientes al
grupo.
Activar el bit de ejecucin para todo los usuarios pertenecientes al
grupo.

S_IRUSR 0100

Activar el bit de lectura para el propietario.

S_IWUSR 0200

Activar el bit de escritura para el propietario.

S_IXUSR 0400

Activar el bit de ejecucin para el propietario.

S_ISVTX 1000

Activa el sticky bit en el fichero.

S_ISGID 2000

Activa el bit de SUID en el fichero.

S_ISUID 4000

Activa el bit de SGID en el fichero.

S_IRWXU

S_IRWXG

S_IRWXO

S_IRUSR + S_IWUSR +
S_IXUSR

Activar el bit de lectura, escritura y ejecucin para el propietario.

S_IRGRP + S_IWGRP + Activar el bit de lectura, escritura y ejecucin para todo los usuarios
S_IXGRP

pertenecientes al grupo.

S_IROTH + S_IWOTH + Activar el bit de lectura, escritura y ejecucin para todo los
S_IXOTH

usuarios.

Tabla: Lista de los posibles valores del argumento mode.


Todos estos valores se definen en un fichero de cabecera , por lo que conviene incluirlo:
#include <sys/stat.h>

Bien, ya sabemos abrir ficheros y crearlos si no existieran, pero no podemos ir dejando ficheros abiertos
sin cerrarlos convenientemente. Ya sabis que C se caracteriza por tratar a sus programadores como
personas responsables y no presupone ninguna niera del estilo del recolector de basuras, o similares.
Para cerrar un fichero basta con pasarle a la syscall close() el descriptor de fichero como argumento:
int close(int fd)

El siguiente paso lgico es poder leer y escribir en los ficheros que manejemos. Para ello emplearemos
dos syscalls muy similares: read() y write(). Aqu tenemos sus prototipos:

ssize_t read( int fd, void *buf, size_t count )

ssize_t write( int fd, void *buf, size_t count )

Ejemplo para abrir archivo:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

//Llamada a libreras
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//Funcin principal
main(int argc, char **argv[])
{
//Declaramos variables
int fd;
char c;
//ABRIR ARCHIVO
//O_RDONLY abre el archivo salida.txt en modo lectura
fd = open("salida.txt",O_RDONLY);
//CONTROLAR SI EXISTE ARCHIVO
if(fd!=-1)
{
//LEER EL ARCHIVO
//El archivo se lee caracter por caracter
while(read(fd,&c,sizeof(c)!=0)){
printf("%c",c);
}
//CERRAR ARCHIVO
close(fd);
}
else{
printf("\nEl archivo no existe");
}
}

Ejemplo para escribir en un archivo:


1
2
3
4
5
6
7
8
9

//Llamada a libreras
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//Funcin principal

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

main(int argc, char **argv[])


{
//Declaramos variables
int fd;
char *c;
//CREAR ARCHIVO
//O_WRONLY abre el archivo salida.txt en modo escritura
//O_CREAT crea el archivo si todava no existe
//S_IRUSR|S_IWUSR son los modos que seleccione: Lectura y Escritura para el usuario
fd = open("salida3.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
//fd = open("salida1.txt",O_WRONLY|00700);
//Ingresamos por teclado lo que queremos guardar en el archivo
scanf("%s",&c);
printf("el tamanho del string es %d\n",sizeof(c));
//Guardamos en el archivo lo que ingresamos por teclado
write(fd,&c,sizeof(c));
//CERRAR ARCHIVO
close(fd);
}

Ejemplo: Abrir un archivo y copiar su contenido en otro:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

//Llamada a libreras
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//Funcin principal
main(int argc, char **argv[])
{
//Declaramos variables
int fd,fd2;
char c;
//ABRIR ARCHIVO U ORIGEN
fd = open("salida.txt",O_RDONLY);
//CREAR ARCHIVO DE DESTINO
fd2 = open("destino.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
//CONTROLAR SI EXISTE ARCHIVO
if(fd!=-1)
{
//LEER EL ARCHIVO
//El archivo se lee caracter por caracter
while(read(fd,&c,sizeof(c)!=0)){
//GUARDAR ARCHIVO NUEVO
write(fd2,&c,sizeof(c));
}

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

//CERRAR ARCHIVO
close(fd);
close(fd2);
fd2 = open("destino.txt",O_RDONLY);
//LEER EL ARCHIVO DESTINO PARA COMPROBAR SI TODO SALIO BIEN
//El archivo se lee caracter por caracter
while(read(fd2,&c,sizeof(c)!=0)){
printf("%c",c);
}
close(fd2);
}
else{
printf("\nEl archivo no existe");
}
}

Otra funcin que puede ser de gran ayuda es lseek(). Muchas veces no queremos posicionarnos al
principio de un fichero para leer o para escribir, sino que lo que nos interesa es posicionarnos en un
desplazamiento concreto relativo al comienzo del fichero, o al final del fichero, etc. La funcin lseek() nos
proporciona esa posibilidad, y tiene el siguiente prototipo:
off_t lseek(int fildes, off_t offset, int whence);

Los parmetros que recibe son bien conocidos, fildes es el descriptor de fichero, offset es el
desplazamiento en el que queremos posicionarnos, relativo a lo que indique whence, que puede tomar
los siguientes valores:
Indicador

Valor Descripcin

SEEK_SET

Posiciona el puntero a offset bytes desde el comienzo del fichero.

SEEK_CUR 1

Posiciona el puntero a offset bytes desde la posicin actual del puntero.

SEEK_END

Posiciona el puntero a offset bytes desde el final del fichero.

Tabla: Lista de los posibles valores del argumento whence.


Por ejemplo, si queremos leer un fichero y saltarnos una cabecera de 8 bytes, podramos hacerlo as:
1
2
3
4
5
6

//Llamada a libreras
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#include<fcntl.h>
#define SIZE 512
//Funcin principal
main( int argc, char **argv[] )
{
int fd, fd2, readbytes;
//En este ejemplo utilizamos un buffer de 512 bytes
char buffer[SIZE];
//ABRIR ARCHIVO U ORIGEN
fd = open("salida.txt",O_RDONLY);
//CREAR ARCHIVO DE DESTINO
fd2 = open("destino2.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IXUSR);
//SALTEAR LOS PRIMEROS 8 bytes.
lseek(fd,8,SEEK_SET);
while( (readbytes = read( fd, buffer, SIZE )) != 0 )
{
/* write( STDOUT, buffer, SIZE ); */
write( fd2, buffer, readbytes );
}
//CERRAR ARCHIVOS
close( fd );
close( fd2 );
}

También podría gustarte