CAPÍTULO 9

Ficheros


Usamos la librería std para trabajar con el sistema de ficheros. Puedes leer la documentación de la misma en:

https://ziglang.org/documentation/master/std/#std.fs


std.fs.


Crear ficheros en una ruta absoluta, manejar errores

Probablemente, bastantes veces nos interesará escribir ficheros en una ruta absoluta. Las rutas absolutas indican el path completo hasta un fichero. Las relativas suponen que nos referimos a una ruta dentro del directorio actual de trabajo (current working directory).

create_file.zig

const std = @import("std");

const print = std.debug.print;

pub fn main() !void {

    const s_dir = "/";

    const s_filename = "instructions.txt";

    const s_path = s_dir ++ s_filename;

    if (std.fs.createFileAbsolute(

        s_path,

        .{},

    )) |o_fx| {

        // cerramos el fichero en diferido

        defer o_fx.close();

        print("Fichero creado\n", .{});

    } else |err_x| {

        // si hay un error lo imprimimos

        print(

            "No se ha podido crear el fichero. Err: {s}.\n",

            .{@errorName(err_x)},

        );

    }

}

$ zig run create_file.zig

No se ha podido crear el fichero. Err: AccessDenied.

Lo más normal, en una máquina real, es que no nos dejen crear el fichero por temas de seguridad en la raíz del sistema de ficheros, a no ser que proporcionemos credenciales de administrador. Si te sucede eso - intenta cambiar el directorio de escritura a /tmp/ a ver que sucede.

Sacó su mapa. La playa se extendía por kilómetros en todas direcciones. Un auténtico desierto de arena bañado por el mar.

-Tiene que estar por aquí -pensó. Todo indicaba que el templo de Orfeo con su cabeza en un altar estaba por aquí.

-Bien… Este sitio es tan bueno como cualquier otro para soltarte -dijo, abriendo la caja que había llevado como mochila desde hace horas.
En cuanto lo activó, el pájaro salió batiendo las alas antes de que su dueño siquiera pudiera decir nada.

- ¿Ya estamos? -graznó el cuervoíde posándose en su hombro.

- Debería. Da una vuelta en espiral. Si ves algo parecido a una entrada o una puerta, me dices.

El pájaro salió volando justo como le había ordenado. El inventor, apenas se había sentado en la arena  cuando el cuervo volvió a posarse en su hombro, dándole un susto.

- Hay una puerta delante de nosotros. -dijo el cuervoíde con su voz agradable de barítono.

Escribir ficheros

Vamos a escribir un fichero en el directorio /tmp/ que suele ser un directorio con acceso a lectura y escritura para todos los usuarios:

write_file.zig

const std = @import("std");

const print = std.debug.print;

pub fn main() !void {

    // crear un fichero en ruta absoluta

    const o_file = try std.fs.createFileAbsolute(

        "/tmp/instructions.txt",

        .{},

    );

    defer o_file.close();

    const n_size = try o_file.write(

        \\ Hola,

        \\ Estas son las instrucciones

        \\ para duplicar un cubo.

        \\ Tendrás que pensar en 3 dimensiones.

        \\

        \\ Mira la fórmula del volumen del cubo: V = a³

        \\ El volumen del cubo doble es: V₂ = 2(a)³

        \\

        \\ Para obtener el lado nuevo a₂

        \\ sabemos que el lado a₂³ = 2(a³)

        \\ a₂ = ³√(2a³)

        \\ a₂ = a ³√2

        \\

        \\ esta raíz cúbica del número 2 no es un número racional,

        \\ no puede construirse con escuadra y compás, ya que con ellos

        \\ solo puedes construir longitudes usando sumas, restas

        \\ multiplicaciones, divisiones y raíces cuadradas.

        \\ Pero las cúbicas no.

        \\

        \\ Ahora, sal inmediatamente por la puerta de entrada.

        \\ Se cierra después de 60 segundos.

        \\ Si sales por la de salida no recordarás nada de esto.

        \\ Dale las gracias al cuervo.

    );

    print("Hemos escrito {} bytes\n", .{n_size});

}

$ zig run write_file.zig

Hemos escrito 731 bytes

- ¿Has visto esa puerta que acaba de desaparecer detrás de ti? - dijo el cuervoíde.

- No. - replicó el inventor, confundido, girándose todo lo rápido que podía. - Pero veo esa puerta que está delante, como bien has dicho.

- Bueno, sea lo que sea, te lo repito otra vez: aquí no cuadra algo, amigo.

- Voy a entrar. Quédate aquí.

- ¡No entres! ¡Eso no puede ser bueno! - gritó el cuervo, mientras su dueño desaparecía por la entrada una vez más.

- ¡A ver, gírate! ¿No ves la puerta que desaparece? - gritó otra vez el cuervo.

- No. -

- Pero…

- Ya, sí, pero ves esa puerta que está delante y…

- Voy a …

- …entrar. - completó el cuervo.

- Hey, acabamos las frases al mismo tiempo amigo. Quédate aquí- sonrió Archytas.

- No, si no pienso entrar - replicó el cuervo.

- ¿Archy? ¿No tienes una sensación extraña - como de haber vivido esto antes? - preguntó el cuervo al verle salir por enésima vez de la puerta que desaparecía inmediatamente.

- No ¿por?

- No. por nada amigo. Ve, corre por la puerta de entrada. Yo me quedo aquí.

- Sí, te lo iba a decir justo- dijo el inventor.

- Oye, una cosa …

- Archytas, ha sido divertido pero llevamos así horas.

- Sí, llevamos horas andando, pero esta es una ocasión única para obtener respuestas. Respuestas que la cabeza de Orfeo conoce y nosotros, los meros mortales no.

- Archy, cada vez que entras por esa puerta, apareces un rato largo después por otra que desaparece detrás de ti. Y no recuerdas lo que ha pasado dentro. Ni siquiera recuerdas haber entrado una vez, ni esta conversación.

Archytas se quedó en silencio un momento procesando las palabras de su amigo.

Leer ficheros

Si hemos escrito antes el fichero en el ejemplo anterior, ahora podemos leerlo.

read_file.zig

const std = @import("std");

const print = std.debug.print;

pub fn main() !void {

    // abrir un fichero en ruta absoluta

    const o_file = try std.fs.openFileAbsolute(

        "/tmp/instructions.txt",

        .{},

    );

    defer o_file.close();

    // usamos un buffer de entrada

    var a_buff: [4096]u8 = undefined;

    const n_size = try o_file.read(&a_buff);

    print("Leídos {} bytes.\n", .{n_size});

    print("{s}\n", .{a_buff[0..n_size]});

}

$ zig run read_file.zig

Leídos 731 bytes.

 Hola,

 Estas son las instrucciones

 para duplicar un cubo...

Después de ver entrar al inventor otra vez, y salir por la puerta que desapareció, el cuervo suspiró y ya no dijo nada cuando le vio entrar otra vez al templo. Hasta él, con su personalidad sarcástica, empezó a preocuparse. Sospechaba que, antes de salir de este bucle les encontrarían los infectados por la plaga.

Pero en esta ocasión en menos de un minuto el inventor volvió por la misma entrada.

- ¿Archy? Has vuelto por la entrada.

- Sí. El templo de Orfeo tiene una entrada que se cierra en un minuto… y una salida. Si sales por la salida, no recuerdas nada. Así que por muchas preguntas que te responda, nunca recuerdas las respuestas.

- ¿Y cómo lo has conseguido saber?

- Me dejé una nota, al parecer. Orfeo es una especie de cabeza androide conectada. Cada vez que entras, el sistema reinicia todo. Conseguí saltar restricciones de seguridad: en el arranque no puedes usar el stdout pero sí puedes escribir ficheros temporales. Dejé un ejecutable que escribe y otro que lee un fichero temporal con una nota cuando arranca.

- ¿Y qué decía la nota?

- Hay que pensar de otra manera, con figuras en tres dimensiones. Y algo más.

El cuervo se quedó esperando.

- Gracias.

- Entonces algo falla Archy, tú nunca dirías eso -rió el cuervo.

Resumen del capítulo
Directorios
© 2025 Zen of Zig