Eric Bergman-Terrell's Blog

Java Programming Tip: Copy a File in Windows and Retain Timestamps and Attributes
March 5, 2015

I recently updated my Java backup program. It now specifies the correct created, accessed, and modified timestamps, and the correct Windows file attributes (system, readonly, archived, and hidden).

This code requires Java 7. Read the updateFileTimestamps and updateDosAttributes methods for the details.

package backup;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributes;
...

public class FileOps {
...
	private final int bufferSize = 512 * 1024;
	

	/**
	 * Copy the specified file to the new folder.
	 * @param sourceRootPath source root
	 * @param destinationRootPath destination root
	 * @param sourceFilePath source file path
	 * @throws Exception
	 */
	public void copyFile(Path sourceRootPath, Path destinationRootPath, Path sourceFilePath) throws Exception {
		FileInputStream inputStream = null;
		FileOutputStream outputStream = null;
		
		Path destinationFilePath = substituteRoot(sourceRootPath, destinationRootPath, sourceFilePath);
		Files.createDirectories(destinationFilePath.getParent());
		
...

		BasicFileAttributeView sourceFileAttributes = null;
		DosFileAttributes sourceDosFileAttributes = null;
		
		try {
			sourceFileAttributes = Files.getFileAttributeView(sourceFilePath, BasicFileAttributeView.class);
			sourceDosFileAttributes = Files.readAttributes(sourceFilePath, DosFileAttributes.class);

			inputStream = new FileInputStream(sourceFilePath.toFile().getAbsolutePath());
			outputStream = new FileOutputStream(destinationFilePath.toFile().getAbsolutePath());
		
			int length;
			
			byte[] buffer = new byte[bufferSize];

			while ((length = inputStream.read(buffer)) > 0) {
...
				outputStream.write(buffer, 0, length);
			}

			outputStream.flush();

...
		}
		finally {
			if (inputStream != null) {
				inputStream.close();
			}
			
			if (outputStream != null) {
				outputStream.close();
			}

			if (sourceFileAttributes != null) {
				updateFileTimestamps(destinationFilePath, sourceFileAttributes.readAttributes());
			}
			
			if (sourceDosFileAttributes != null) {
				updateDosAttributes(destinationFilePath, sourceDosFileAttributes);
			}
		}
	}

	private void updateFileTimestamps(Path destinationFilePath, BasicFileAttributes sourceFileAttributes) throws IOException {
		Files.setAttribute(destinationFilePath, "creationTime", sourceFileAttributes.creationTime());
		Files.setAttribute(destinationFilePath, "lastAccessTime", sourceFileAttributes.lastAccessTime());

		Files.setLastModifiedTime(destinationFilePath, sourceFileAttributes.lastModifiedTime());
	}
	
	private void updateDosAttributes(Path destinationFilePath, DosFileAttributes sourceDosFileAttributes) throws IOException {
		Files.setAttribute(destinationFilePath, "dos:archive", sourceDosFileAttributes.isArchive());
		Files.setAttribute(destinationFilePath, "dos:hidden", sourceDosFileAttributes.isHidden());
		Files.setAttribute(destinationFilePath, "dos:readonly", sourceDosFileAttributes.isReadOnly());
		Files.setAttribute(destinationFilePath, "dos:system", sourceDosFileAttributes.isSystem());
	}

...
}

Keywords: Java, Java 7, Windows, Filesystem, Timestamps, Attributes

Reader Comments

Comment on this Blog Post

Recent Posts

TitleDate
EBTCalc (Android) Version 1.53 is now availableMay 19, 2024
Vault 3 Security EnhancementsOctober 24, 2023
Vault 3 is now available for Apple OSX M2 Mac Computers!September 18, 2023
Vault (for Desktop) Version 0.77 ReleasedMarch 26, 2023
EBTCalc (Android) Version 1.44 is now availableOctober 12, 2021
Vault (Desktop) Version 0.72 ReleasedOctober 6, 2021
EBT Compass is Now Available for Android DevicesJune 2, 2021