You've hit on the key -- that the files are not connected.
Looking at the code, Archive::Zip appears to always first access the central directory information, which is at the end of the file. For files that are not fully sent, that never works since it's the last part of the file that's missing. It makes sense to build the code around the central directory -- it's surely faster than parsing the entire zip file to get the pieces that are available. So I think a recovery method would have to try and piece things together the slow way as you state.