I guess but I would still think at least for storage devices ultimately you're looking at a linear array of bytes from the logical perspective. That logical array of bytes may be blocks with control data, may be sectors, something else, but in the end I want write(2) to put the number of bytes I say at what would in the physical structure of the device represent the logical address <xyz>, because my expectation would be to in another breath ensure a file descriptor seeked to the same address in that logical array reads back that physical data from the media.
Even with tapes I seem to recall that early attention was given to ensuring the magtape drivers in UNIX could, however inefficient, treat magtape like a random access character device. Sure maybe this means reading out a whole block/record, editing it, rewinding the tape, and recording the whole record again just to edit one byte,
I don't know a whole lot about tape, but I found this at
https://en.wikipedia.org/wiki/End-of-file#tape_mark because I thought tape marks might make a counter-example:
In the ANSI X3.27-1969
magnetic tape standard, the end of file was indicated by a
tape mark, which consisted of a gap of approximately 3.5 inches of tape followed by a single byte containing the character 0x13 (hex) for
nine-track tapes and 017 (octal) for
seven-track tapes.
https://en.wikipedia.org/wiki/Magnetic-tape_data_storage#IBM_formats says something about NRZI encoding, so I suppose that sure, you could maybe still have a linear array of bytes, as you suggested, and we could say that our interface to this tape presents one byte per 1/1024th of an inch or something, and:
- if the first byte is 0 and the second is a 1, then the actual data presented to the user should be a 0
- if the first byte is a 1 and the second is a 0, then the actual data presented to the user should be a 1
- if there is a run of 3500 or so zeros followed by the 0s and 1s that make up 0x13 then you found a tape mark
Hopefully my encoding scheme based on vague memories isn't too confusing for the purposes of this conversation.
I think that in practice, you wouldn't want to do this, because:
- you probably also need to detect the bit transitions to do clock recovery in hardware; and
- it would be slower to have twice the number of bits sent to the CPU and then translated back into the desired number of bits, particularly for older machines.
Others might have better arguments than me, because I don't really know too much about how this kind of hardware would work.
I think though that ultimately you're not really looking at a linear array of bytes, but analog signals (gross!).