In Linux, a hard disk is represented by a device file in the /dev directory (example: /dev/sda or /dev/hda), and its partitions are represented by the same names but with an additional numeric suffix.
You can read those files using standard Java file I/O APIs like RandomAccessFile or FileInputStream. You need permissions to access those /dev/ files - typically root or sudoers or explicit permission.
You can say raf.seek(1024) and raf.read(buffer, 0, 512) and it'll read whatever 512 bytes are at offset 1024 from start of hard disk or partition.
The kernel driver does all the hard work of translating offset to the hard disk's geometry, such as cylinder+sector.
I suspect the concept is the same in MacOS, because MacOS is a *nix, but the device naming may be different.
Not sure about Windows though.
But even if it's possible, I feel java is simply the wrong tool for this job - partly because its
philosophy is that of a high level language that usually sits far from low level system tasks, and partly because performance (time taken) would likely be bad.