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.