Home > other >  Append zero bytes to a file
Append zero bytes to a file

Time:02-16

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))

CodePudding user response:

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
  ...

CodePudding user response:

write(contentsOf:) takes any DataProtocol as a parameter. You can create a Repeated<UInt8>, which conforms to DataProtocol, using repeatElement:

try fileHandle.write(contentsOf: repeatElement(0, count: someCount))

Repeated<T> is an efficient representation of a collection with only one unique element repeated n times. According to the implementation, when someCount > 0, this will only create one Data instance containing just one 0.

  • Related