将零字节附加到文件

Append zero bytes to a file

有没有办法在不必创建空数据值的情况下将零字节附加到文件?

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

write(contentsOf:) 接受任何 DataProtocol 作为参数。您可以使用 repeatElement:

创建符合 DataProtocolRepeated<UInt8>
try fileHandle.write(contentsOf: repeatElement(0, count: someCount))

Repeated<T> 是一个集合的有效表示,只有一个唯一元素重复 n 次。根据 implementation,当 someCount > 0 时,这只会创建一个 Data 实例,其中只包含一个 0.

您可以使用 truncate(atOffset:) 方法将空字节附加到文件。来自文档:

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.

为此目的不需要数据值或写入操作。

示例:

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

使用 dtruss 的系统调用跟踪显示使用 ftruncate 系统调用可以有效地扩展文件:

$ sudo dtruss /path/to/program
  ...
  920/0x3c0b:  open("file.txt[=15=]", 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
  ...