Skip to content

Añadir una línea a un archivo snippet

Agrega una línea a un archivo existente sin leerlo ni reescribirlo: la forma de toda escritura de log, historial o archivo de cola.

Agrega una línea a un archivo existente sin leerlo ni reescribirlo: la forma de toda escritura de log, historial o archivo de cola. El patrón es abrir en modo append y escribir tu propio salto de línea final, porque el append de ningún lenguaje lo añade por ti; si lo olvidas, la próxima línea queda pegada a la última. En POSIX, O_APPEND hace que cada escritura corta caiga al final del archivo de forma atómica, así que varios escritores concurrentes intercalan líneas completas en lugar de pisarse entre sí — una garantía que se degrada cuando las líneas superan el tamaño del búfer del pipe. SQL se omite: el motor no puede añadir a un archivo en tu máquina, y COPY ... TO PROGRAM 'cat >> log' se ejecuta del lado del servidor bajo superusuario — un truco, no una respuesta.

Receta ejecutable · 14 lenguajes
Files & Datafilesappendiologging

Every language

14 lenguajes, copy-ready. One at a time with syntax highlighting, or all inline.

JSJavaScript
import { appendFile } from 'node:fs/promises';

await appendFile('app.log', 'deploy finished\n', 'utf8');

appendFile opens with O_APPEND, writes, and closes per call — fine for occasional lines. For a hot loop, open once with (await open('app.log', 'a')).write(...) and reuse the handle.

TSTypeScript
import { appendFile } from 'node:fs/promises';

const line: string = `deploy finished at ${new Date().toISOString()}\n`;
await appendFile('app.log', line, 'utf8');

Identical runtime to the JavaScript version — the type annotation just stops a non-string sneaking into the buffer. It creates the file if it is missing.

GoGo
package main

import "os"

func main() {
	f, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	if _, err := f.WriteString("deploy finished\n"); err != nil {
		panic(err)
	}
}

os.O_APPEND makes the kernel position every write at end-of-file. Pass O_CREATE or a missing file is an error, and never O_TRUNC — that empties the log you came to extend.

RsRust
use std::fs::OpenOptions;
use std::io::Write;

fn main() -> std::io::Result<()> {
    let mut file = OpenOptions::new()
        .append(true)
        .create(true)
        .open("app.log")?;
    writeln!(file, "deploy finished")?;
    Ok(())
}

Stdlib only. writeln! appends the '\n' for you — write! does not — and .append(true) maps to O_APPEND rather than seeking once.

PHPPHP
<?php
file_put_contents('app.log', "deploy finished\n", FILE_APPEND | LOCK_EX);

FILE_APPEND is the append flag; LOCK_EX takes an advisory lock so concurrent PHP processes don't interleave mid-line. For a stream of lines keep one fopen($fh, 'a') handle open instead of reopening per write.

PyPython
from pathlib import Path

with Path("app.log").open("a", encoding="utf-8") as f:
    f.write("deploy finished\n")

Mode "a" positions every write at end-of-file ("a+" additionally allows reading). The with block flushes and closes — an abandoned handle can lose buffered lines on exit.

CC
#include <stdio.h>

int main(void) {
    FILE *f = fopen("app.log", "a");
    if (f == NULL) {
        perror("fopen");
        return 1;
    }
    if (fputs("deploy finished\n", f) == EOF) {
        fclose(f);
        return 1;
    }
    return fclose(f) == 0 ? 0 : 1;
}

Stdio "a" mode creates the file if needed and seeks to end on every write. fputs writes exactly the string — the '\n' is on you — and only fclose (or fflush) drains the buffer.

C++C++
#include <fstream>

int main() {
    std::ofstream log("app.log", std::ios::app);
    log << "deploy finished\n";
}

std::ios::app seeks to end before each write (std::ios::ate seeks once at open, then writes wherever you leave the put pointer). The destructor flushes on scope exit.

C#C#
using System.IO;

File.AppendAllText("app.log", "deploy finished\n");

AppendAllText writes exactly what you hand it — the newline is your job; use Environment.NewLine when you want the platform's convention. It reopens per call, so a StreamWriter(new FileStream(..., FileMode.Append)) wins in tight loops.

JvJava
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class AppendLine {
    public static void main(String[] args) throws IOException {
        Files.writeString(
            Path.of("app.log"),
            "deploy finished" + System.lineSeparator(),
            StandardOpenOption.CREATE, StandardOpenOption.APPEND);
    }
}

StandardOpenOption.APPEND is the flag; without CREATE a missing file throws NoSuchFileException. writeString writes verbatim, so the newline is explicit — System.lineSeparator() for the platform's, "\n" for log files that travel.

SwSwift
import Foundation

let url = URL(fileURLWithPath: "app.log")
let handle = try FileHandle(forWritingTo: url)
try handle.seekToEnd()
try handle.write(contentsOf: Data("deploy finished\n".utf8))
try handle.close()

Foundation's String.write(to:) replaces the file even with atomically: false — appending means FileHandle plus seekToEnd() before every write. FileHandle(forWritingTo:) fails if the file doesn't exist; create it first with FileManager.default.createFile(atPath:contents:nil).

KtKotlin
import java.io.File

fun main() {
    File("app.log").appendText("deploy finished\n")
}

appendText reopens the file per call and encodes as UTF-8; it adds no newline. For many lines, File('app.log').outputStream().bufferedWriter().use { it.appendLine(...) } keeps one handle.

RbRuby
File.open('app.log', 'a') { |f| f.puts 'deploy finished' }

Mode 'a' appends; the block closes the handle even on an exception. puts adds the newline that write would omit — a trailing write without one welds the next line onto the last.

ZigZig
const std = @import("std");

pub fn main() !void {
    const file = try std.fs.cwd().createFile("app.log", .{ .truncate = false });
    defer file.close();
    try file.seekFromEnd(0);
    try file.writeAll("deploy finished\n");
}

createFile defaults to truncate: true — pass .truncate = false to keep existing bytes, then seekFromEnd(0) before writing. std.fs has no append flag in the create options, so the explicit seek is the idiom.