Adding text to the end of a file without disturbing what’s already there

Append a String to a File — CodeForge
CodeForge — Programming Reference

Append a String to a File

Adding text to the end of a file without disturbing what’s already there — the open mode that matters, and why concurrent appends need more care than they look like they do.

Difficulty: Beginner Languages: Python · Java · C Read: ~8 min
In this article
  1. Append mode versus write mode — the distinction that matters most
  2. Code in Python, Java, and C
  3. What “append” actually guarantees at the OS level
  4. Encoding and newline pitfalls
  5. Concurrent appends from multiple processes
  6. When append mode is the wrong tool

01 Append mode versus write mode — the distinction that matters most

Opening a file for output almost always offers at least two distinct modes, and confusing them is one of the most common small mistakes in file-handling code: write mode truncates the file to zero length the moment it’s opened, discarding anything already in it, while append mode preserves existing content and positions every subsequent write at the current end of the file. A program that means to add a new log line to an existing log file, but accidentally opens it in plain write mode instead of append mode, will silently erase the entire existing log on its very first write — a bug that’s easy to introduce and, because it doesn’t crash or raise any error, easy to miss until someone notices the log history is gone.

This single mode flag is the entire conceptual core of this article. Everything else — encoding, concurrency, newline handling — is a refinement around that one foundational choice.

02 Code in Python, Java, and C

Python’s built-in open() function uses the mode string "a" for append, mirroring the C convention it’s built on top of.

append_string.py
def append_to_file(path, text):
    with open(path, "a", encoding="utf-8") as f:
        f.write(text)

The with statement guarantees the file is properly closed even if an exception occurs partway through the write — a small habit worth keeping consistently, since a file left open due to an unhandled error can, on some platforms, leave the last write incompletely flushed to disk.

AppendToFile.java
public static void appendToFile(String path, String text) throws IOException {
    Files.write(
        Paths.get(path),
        text.getBytes(StandardCharsets.UTF_8),
        StandardOpenOption.CREATE,
        StandardOpenOption.APPEND
    );
}

Java’s explicit option flags spell out the intent unusually clearly: CREATE says to make the file if it doesn’t already exist, and APPEND says to add to the end rather than overwrite — two separate decisions that other languages often fold into a single mode character.

append_string.c
#include <stdio.h>

int append_to_file(const char* path, const char* text) {
    FILE* f = fopen(path, "a");
    if (!f) return -1;

    fputs(text, f);
    fclose(f);
    return 0;
}

03 What “append” actually guarantees at the OS level

Append mode isn’t just a convenience implemented purely in the language’s standard library — on POSIX systems, opening a file with the append flag set is a property the operating system itself enforces at the kernel level. Specifically, the O_APPEND flag guarantees that every single write operation is atomically positioned at the current end of the file immediately before writing, as a single indivisible step, rather than the application separately seeking to the end and then writing as two distinct operations that something else could interleave with.

Why this distinction matters: if two processes both seek-then-write instead of using true append mode, a write from one process can land in between the seek and write of the other, corrupting both outputs. True OS-level append mode closes that gap entirely for single writes, which is precisely why it’s the right tool for anything multiple processes might write to concurrently, such as a shared log file.

04 Encoding and newline pitfalls

  • Always specify text encoding explicitly. Relying on a platform’s default encoding can produce different output depending on which machine the code runs on — an easy source of “works on my machine” bugs.
  • Decide on newline conventions up front. Windows traditionally uses a carriage-return-plus-line-feed pair while Unix-like systems use a single line feed; mixing styles within a log file can confuse line-counting utilities or strict parsers downstream.
  • Remember that appended text doesn’t get an automatic newline. Calling an append function repeatedly without explicitly adding a line terminator each time will run every appended string together on a single line.
  • Watch for partial writes on very large strings. Most standard library write functions handle this internally, but code working at a lower level with raw system calls should confirm the full byte count was actually written.

05 Concurrent appends from multiple processes

ScenarioSafe?Why
Single small write per call, true append mode, same machineYesThe OS guarantees the seek-and-write is atomic for each individual write
One logical message split across multiple write callsNoAnother process’s append can land between your two writes, interleaving the output
Append mode over a network filesystemDependsNot every network filesystem implementation honors atomic append semantics the same way local disks do

The practical takeaway: build each appended log line or record as a single complete string before calling the write function once, rather than writing it in pieces across multiple calls — that keeps each append atomic under the OS guarantee, even when several independent processes are appending to the same file at the same time.

06 When append mode is the wrong tool

  • Updating existing content. If the goal is to modify a line that’s already in the file rather than add a new one at the end, append mode can’t help — that requires either rewriting the whole file or using more advanced random-access techniques.
  • Enforcing a maximum file size. Append mode has no built-in awareness of how large the file has grown; log rotation needs to be handled as separate logic layered on top.
  • Structured formats like JSON arrays or XML documents. Naively appending a new entry to the end of a file containing a single JSON array produces invalid syntax — formats like newline-delimited JSON exist specifically to be append-friendly in a way a single large structured document is not.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *