Thanks for the other answers. Unfortunately, I'm not in a position to install additional software, so the ddrescue option is out. The head/tail solution is interesting (I didn't realise you could supply + to tail), but scanning through the data makes it quite slow.
I ended up writing a small python script to do what I wanted. The buffer size should probably be tuned to be the same as some external buffer setting, but using the value below is performant enough on my system.
#!/usr/local/bin/python
import sys
BUFFER_SIZE = 100000
# Read args
if len(sys.argv) < 4:
print >> sys.stderr, "Usage: %s input_file start_pos length" % (sys.argv[0],)
sys.exit(1)
input_filename = sys.argv[1]
start_pos = int(sys.argv[2])
length = int(sys.argv[3])
# Open file and seek to start pos
input = open(sys.argv[1])
input.seek(start_pos)
# Read and write data in chunks
while length > 0:
# Read data
buffer = input.read(min(BUFFER_SIZE, length))
amount_read = len(buffer)
# Check for EOF
if not amount_read:
print >> sys.stderr, "Reached EOF, exiting..."
sys.exit(1)
# Write data
sys.stdout.write(buffer)
length -= amount_read