public static void copyFile(BufferFile srcFile, BufferFile destFile, ChangeMap changeMap,
			TaskMonitor monitor) throws IOException, CancelledException {
		if (destFile.isReadOnly()) {
			throw new IOException("File is read-only");
		}

		if (srcFile.getBufferSize() != destFile.getBufferSize()) {
			throw new IOException("Buffer sizes differ");
		}

		monitor = TaskMonitor.dummyIfNull(monitor);

		int srcBlockCnt;
		boolean headerTransferRequired;

		try (InputBlockStream in = getInputBlockStream(srcFile, changeMap)) {
			headerTransferRequired = !in.includesHeaderBlock();
			srcBlockCnt = in.getBlockCount();
			monitor.initialize(srcBlockCnt + 2);
			try (OutputBlockStream out = getOutputBlockStream(destFile, in.getBlockCount())) {
				completeBlockStreamTransfer(in, out, monitor);
			}
		}
		finally {
			// circumvent other exceptions if cancelled
			monitor.checkCancelled();
		}

		if (headerTransferRequired) {
			destFile.clearParameters();
			String[] parmNames = srcFile.getParameterNames();
			for (String name : parmNames) {
				destFile.setParameter(name, srcFile.getParameter(name));
			}
			monitor.setProgress(srcBlockCnt + 1);

			// Copy free index list
			destFile.setFreeIndexes(srcFile.getFreeIndexes());
		}
		monitor.setProgress(srcBlockCnt + 2);
	}
Copy the complete content of a specified srcFile into a destFile excluding file ID.  Both
files remain open.
@param srcFile open buffer file
@param destFile empty buffer file which is open for writing.
@param changeMap optional change map which indicates those buffers which must be copied.
Any buffer index outside the range of the change map will also be copied.
@param monitor progress monitor
@throws IOException if IO error occurs.
@throws CancelledException if the monitor cancels the operation.
Ghidra/Framework/DB/src/main/java/db/buffers/LocalBufferFile.java