swiftfilehandle

Append zero bytes to a file


Is there a way to append zero bytes to a file without having to create a empty Data value?

let handle : FileHandle = ...
let count : Int = ...
try handle.seekToEnd()
try handle.write(contentsOf: Data(repeating: 0, count: count))

Solution

  • You can append null bytes to a file with the truncate(atOffset:) method. From the documentation:

    Truncates or extends the file represented by the file handle to a specified offset within the file and puts the file pointer at that position.

    If the file is extended (if offset is beyond the current end of file), the added characters are null bytes.

    No data value or write operation is needed for this purpose.

    Example:

    let handle : FileHandle = ...
    let numberOfBytesToAppend: UInt64 = ...
    var size = try handle.seekToEnd()     // Get current size
    size += numberOfBytesToAppend         // Compute new size
    try handle.truncate(atOffset: size)   // Extend file
    try handle.close()
    

    A system call trace with dtruss shows that extending the file is done efficiently with the ftruncate system call:

    $ sudo dtruss /path/to/program
      ...
      920/0x3c0b:  open("file.txt\0", 0x1, 0x0)      = 3 0
      920/0x3c0b:  fstat64(0x3, 0x7FFEE381B358, 0x0)         = 0 0
      920/0x3c0b:  lseek(0x3, 0x0, 0x2)      = 6000 0
      920/0x3c0b:  lseek(0x3, 0x1B58, 0x0)       = 7000 0
      920/0x3c0b:  ftruncate(0x3, 0x1B58, 0x0)       = 0 0
      920/0x3c0b:  close(0x3)        = 0 0
      ...