End of archive
Tar has no index and no count of entries, so the end of the archive is marked in the stream itself: two blocks of zeros where the next header would be. Everything in the archive, including that marker, is a whole number of 512-byte blocks.
Padding file data
A file’s data starts in the block after its header and fills as many blocks as it
needs. The last block is padded with zeros, so a file of n bytes takes
n rounded up to the next multiple of 512. The next header always starts on a
block boundary, and a reader finds it by rounding up the size in the
header.
The two zero blocks
After the last entry come two blocks of 512 zero bytes. A reader stops at the first block that is all zeros, since a real header never is; its checksum would fail. GNU tar warns about “a lone zero block” when the first zero block is not followed by a second.
For hello.txt, the 13-byte file used on the
header block page, the archive written by
bsdtar is four blocks long:
0Header forhello.txt512 bytes512Data 13 bytes of text and 499 zeros512 bytes1024Zero block the first end marker512 bytes1536Zero block the second end marker512 bytes
Records and the blocking factor
Tape drives work best with large writes, so tar writes its blocks in groups called records. The number of blocks in a record is the blocking factor, and the default is 20, giving records of 10,240 bytes. The final record is filled with zeros after the two end blocks. This is why a tar file made by GNU tar is always a multiple of 10,240 bytes, so the one-file archive above would be 10,240 bytes long rather than 2,048. Writers that do not pad to a record, such as bsdtar writing to a disk file here, stop after the two zero blocks.
Appending and joining
To add entries to an archive, tar overwrites the two zero blocks with the new headers
and writes new zero blocks after them. Joining two archives with a plain file copy
leaves the first archive’s zero blocks in the middle, so most readers stop there. GNU
tar’s --ignore-zeros option reads past them to the entries beyond.
A compressed tar file such as .tar.gz compresses the whole stream,
padding and end blocks included. Runs of zeros compress to almost nothing, so the
padding costs very little.