daniel file manager 수정 반영

This commit is contained in:
2026-04-08 15:19:46 +09:00
parent 5651fd7819
commit 593db69245

View File

@@ -33,6 +33,9 @@ public class FileManagerService {
private static final String BASE_DATA_PATH = "/data"; private static final String BASE_DATA_PATH = "/data";
private static final long MAX_PATH_LENGTH = 500; private static final long MAX_PATH_LENGTH = 500;
@Value("${train.docker.base_path}")
private String basePath;
@Value("${train.docker.request_dir}") @Value("${train.docker.request_dir}")
private String requestDir; private String requestDir;
@@ -53,7 +56,7 @@ public class FileManagerService {
*/ */
public FileManagerDto.ListFilesRes listFiles(FileManagerDto.ListFilesReq request) { public FileManagerDto.ListFilesRes listFiles(FileManagerDto.ListFilesReq request) {
String targetPath = String targetPath =
request.getDirectoryPath() != null ? request.getDirectoryPath() : BASE_DATA_PATH; request.getDirectoryPath() != null ? request.getDirectoryPath() : BASE_DATA_PATH;
boolean recursive = request.getRecursive() != null && request.getRecursive(); boolean recursive = request.getRecursive() != null && request.getRecursive();
@@ -63,32 +66,32 @@ public class FileManagerService {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
log.debug("유효하지 않은 경로: {}", targetPath); log.debug("유효하지 않은 경로: {}", targetPath);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
Path directory = Paths.get(targetPath); Path directory = Paths.get(targetPath);
if (!Files.exists(directory)) { if (!Files.exists(directory)) {
log.debug("디렉토리가 존재하지 않습니다: {}", targetPath); log.debug("디렉토리가 존재하지 않습니다: {}", targetPath);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
if (!Files.isDirectory(directory)) { if (!Files.isDirectory(directory)) {
log.debug("디렉토리 경로가 아닙니다: {}", targetPath); log.debug("디렉토리 경로가 아닙니다: {}", targetPath);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
List<FileManagerDto.FileInfo> files = new ArrayList<>(); List<FileManagerDto.FileInfo> files = new ArrayList<>();
@@ -98,22 +101,22 @@ public class FileManagerService {
if (recursive) { if (recursive) {
// 재귀적으로 모든 하위 파일 조회 // 재귀적으로 모든 하위 파일 조회
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
files.add(createFileInfo(file)); files.add(createFileInfo(file));
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@Override @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) { if (!dir.equals(directory)) {
files.add(createFileInfo(dir)); files.add(createFileInfo(dir));
}
return FileVisitResult.CONTINUE;
} }
}); return FileVisitResult.CONTINUE;
}
});
} else { } else {
// 현재 디렉토리의 파일만 조회 // 현재 디렉토리의 파일만 조회
try (Stream<Path> stream = Files.list(directory)) { try (Stream<Path> stream = Files.list(directory)) {
@@ -131,19 +134,19 @@ public class FileManagerService {
} catch (IOException e) { } catch (IOException e) {
log.debug("파일 목록 조회 중 오류 발생: {}", targetPath, e); log.debug("파일 목록 조회 중 오류 발생: {}", targetPath, e);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(files) .files(files)
.totalCount(files.size()) .totalCount(files.size())
.totalSize(totalSize) .totalSize(totalSize)
.build(); .build();
} }
/** /**
@@ -205,15 +208,15 @@ public class FileManagerService {
} }
String message = String message =
String.format("%d개 파일 삭제 성공, %d개 파일 삭제 실패", deletedFiles.size(), failedFiles.size()); String.format("%d개 파일 삭제 성공, %d개 파일 삭제 실패", deletedFiles.size(), failedFiles.size());
return FileManagerDto.DeleteFileRes.builder() return FileManagerDto.DeleteFileRes.builder()
.deletedFiles(deletedFiles) .deletedFiles(deletedFiles)
.failedFiles(failedFiles) .failedFiles(failedFiles)
.successCount(deletedFiles.size()) .successCount(deletedFiles.size())
.failureCount(failedFiles.size()) .failureCount(failedFiles.size())
.message(message) .message(message)
.build(); .build();
} }
/** FileInfo 객체 생성 */ /** FileInfo 객체 생성 */
@@ -222,45 +225,45 @@ public class FileManagerService {
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
return FileManagerDto.FileInfo.builder() return FileManagerDto.FileInfo.builder()
.fileName(path.getFileName().toString()) .fileName(path.getFileName().toString())
.filePath(path.toString()) .filePath(path.toString())
.fileSize(attrs.isRegularFile() ? attrs.size() : null) .fileSize(attrs.isRegularFile() ? attrs.size() : null)
.isFile(attrs.isRegularFile()) .isFile(attrs.isRegularFile())
.isDirectory(attrs.isDirectory()) .isDirectory(attrs.isDirectory())
.lastModified( .lastModified(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()), Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()),
ZoneId.systemDefault())) ZoneId.systemDefault()))
.readable(Files.isReadable(path)) .readable(Files.isReadable(path))
.writable(Files.isWritable(path)) .writable(Files.isWritable(path))
.build(); .build();
} catch (IOException e) { } catch (IOException e) {
log.warn("파일 정보 조회 실패: {}", path, e); log.warn("파일 정보 조회 실패: {}", path, e);
return FileManagerDto.FileInfo.builder() return FileManagerDto.FileInfo.builder()
.fileName(path.getFileName().toString()) .fileName(path.getFileName().toString())
.filePath(path.toString()) .filePath(path.toString())
.build(); .build();
} }
} }
/** 디렉토리 재귀 삭제 */ /** 디렉토리 재귀 삭제 */
private void deleteDirectoryRecursively(Path directory) throws IOException { private void deleteDirectoryRecursively(Path directory) throws IOException {
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException { throws IOException {
Files.delete(file); Files.delete(file);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@Override @Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir); Files.delete(dir);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
}); });
} }
/** 디렉토리가 비어있는지 확인 */ /** 디렉토리가 비어있는지 확인 */
@@ -299,12 +302,12 @@ public class FileManagerService {
// 모델이 존재하지 않으면 빈 데이터 반환 // 모델이 존재하지 않으면 빈 데이터 반환
if (model == null) { if (model == null) {
return FileManagerDto.ModelFilePathRes.builder() return FileManagerDto.ModelFilePathRes.builder()
.modelUuid(modelUuid.toString()) .modelUuid(modelUuid.toString())
.requestPath(null) .requestPath(null)
.responsePath(null) .responsePath(null)
.requestFiles(new ArrayList<>()) .requestFiles(new ArrayList<>())
.responseFiles(new ArrayList<>()) .responseFiles(new ArrayList<>())
.build(); .build();
} }
// request_path: tb_model_master.request_path 컬럼 값 사용 // request_path: tb_model_master.request_path 컬럼 값 사용
@@ -327,12 +330,12 @@ public class FileManagerService {
List<FileManagerDto.FileInfo> responseFiles = getFilesInDirectory(responsePath); List<FileManagerDto.FileInfo> responseFiles = getFilesInDirectory(responsePath);
return FileManagerDto.ModelFilePathRes.builder() return FileManagerDto.ModelFilePathRes.builder()
.modelUuid(modelUuid.toString()) .modelUuid(modelUuid.toString())
.requestPath(requestPath) .requestPath(requestPath)
.responsePath(responsePath) .responsePath(responsePath)
.requestFiles(requestFiles) .requestFiles(requestFiles)
.responseFiles(responseFiles) .responseFiles(responseFiles)
.build(); .build();
} }
/** /**
@@ -348,10 +351,10 @@ public class FileManagerService {
// 데이터셋이 존재하지 않으면 빈 데이터 반환 // 데이터셋이 존재하지 않으면 빈 데이터 반환
if (dataset == null) { if (dataset == null) {
return FileManagerDto.DatasetFilePathRes.builder() return FileManagerDto.DatasetFilePathRes.builder()
.datasetUuid(datasetUuid.toString()) .datasetUuid(datasetUuid.toString())
.datasetPath(null) .datasetPath(null)
.files(new ArrayList<>()) .files(new ArrayList<>())
.build(); .build();
} }
// dataset_path 컬럼이 있으면 사용, 없으면 request_dir + uuid 사용 // dataset_path 컬럼이 있으면 사용, 없으면 request_dir + uuid 사용
@@ -364,10 +367,10 @@ public class FileManagerService {
List<FileManagerDto.FileInfo> files = getFilesInDirectory(datasetPath); List<FileManagerDto.FileInfo> files = getFilesInDirectory(datasetPath);
return FileManagerDto.DatasetFilePathRes.builder() return FileManagerDto.DatasetFilePathRes.builder()
.datasetUuid(datasetUuid.toString()) .datasetUuid(datasetUuid.toString())
.datasetPath(datasetPath) .datasetPath(datasetPath)
.files(files) .files(files)
.build(); .build();
} }
/** /**
@@ -383,35 +386,35 @@ public class FileManagerService {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
log.debug("유효하지 않은 경로: {}", directoryPath); log.debug("유효하지 않은 경로: {}", directoryPath);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
Path directory = Paths.get(directoryPath); Path directory = Paths.get(directoryPath);
if (!Files.exists(directory)) { if (!Files.exists(directory)) {
log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath); log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
if (!Files.isDirectory(directory)) { if (!Files.isDirectory(directory)) {
log.debug("디렉토리 경로가 아닙니다: {}", directoryPath); log.debug("디렉토리 경로가 아닙니다: {}", directoryPath);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
final long[] totalSize = {0}; final long[] totalSize = {0};
@@ -420,41 +423,41 @@ public class FileManagerService {
try { try {
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
totalSize[0] += attrs.size(); totalSize[0] += attrs.size();
fileCount[0]++; fileCount[0]++;
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@Override @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) { if (!dir.equals(directory)) {
directoryCount[0]++; directoryCount[0]++;
}
return FileVisitResult.CONTINUE;
} }
}); return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) { } catch (IOException e) {
log.debug("디렉토리 용량 체크 중 오류 발생: {}", directoryPath, e); log.debug("디렉토리 용량 체크 중 오류 발생: {}", directoryPath, e);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(fileCount[0]) .fileCount(fileCount[0])
.directoryCount(directoryCount[0]) .directoryCount(directoryCount[0])
.totalSize(totalSize[0]) .totalSize(totalSize[0])
.totalSizeFormatted(formatFileSize(totalSize[0])) .totalSizeFormatted(formatFileSize(totalSize[0]))
.build(); .build();
} }
/** /**
@@ -471,18 +474,18 @@ public class FileManagerService {
for (String modelNo : modelNumbers) { for (String modelNo : modelNumbers) {
// model_no로 가장 최근 모델 조회 (del_yn = false) // model_no로 가장 최근 모델 조회 (del_yn = false)
List<ModelMasterEntity> models = List<ModelMasterEntity> models =
modelMngRepository.findByModelNoAndDelYnOrderByCreatedDttmDesc(modelNo, false); modelMngRepository.findByModelNoAndDelYnOrderByCreatedDttmDesc(modelNo, false);
if (models.isEmpty()) { if (models.isEmpty()) {
// 모델이 없으면 대기 상태 // 모델이 없으면 대기 상태
modelStatuses.add( modelStatuses.add(
FileManagerDto.ModelExecutionStatusRes.builder() FileManagerDto.ModelExecutionStatusRes.builder()
.modelNo(modelNo) .modelNo(modelNo)
.statusMessage(modelNo + " 모델은 대기 중입니다.") .statusMessage(modelNo + " 모델은 대기 중입니다.")
.step1State(null) .step1State(null)
.step2State(null) .step2State(null)
.currentStep(null) .currentStep(null)
.build()); .build());
continue; continue;
} }
@@ -514,19 +517,19 @@ public class FileManagerService {
} }
modelStatuses.add( modelStatuses.add(
FileManagerDto.ModelExecutionStatusRes.builder() FileManagerDto.ModelExecutionStatusRes.builder()
.modelNo(modelNo) .modelNo(modelNo)
.statusMessage(statusMessage) .statusMessage(statusMessage)
.step1State(step1State) .step1State(step1State)
.step2State(step2State) .step2State(step2State)
.currentStep(currentStep) .currentStep(currentStep)
.build()); .build());
} }
return FileManagerDto.AllModelsExecutionStatusRes.builder() return FileManagerDto.AllModelsExecutionStatusRes.builder()
.modelStatuses(modelStatuses) .modelStatuses(modelStatuses)
.runningCount(runningCount) .runningCount(runningCount)
.build(); .build();
} }
/** 디렉토리 내 파일 목록 조회 (내부 사용) */ /** 디렉토리 내 파일 목록 조회 (내부 사용) */
@@ -567,49 +570,49 @@ public class FileManagerService {
} }
/** /**
* 저장공간 정보 조회 (남은 공간 포함) 고정 경로: /home/kcomu/data * 저장공간 정보 조회 (남은 공간 포함) 고정 경로: train.docker.base_path 설정값 사용
* *
* @return 저장공간 정보 (사용량, 남은 공간, 디스크 용량) * @return 저장공간 정보 (사용량, 남은 공간, 디스크 용량)
*/ */
public FileManagerDto.StorageSpaceRes getStorageSpaceInfo() { public FileManagerDto.StorageSpaceRes getStorageSpaceInfo() {
// 고정 경로: /home/kcomu/data // 설정값에서 경로 가져오기 (train.docker.base_path)
String directoryPath = "/home/kcomu/data"; String directoryPath = basePath;
Path directory = Paths.get(directoryPath); Path directory = Paths.get(directoryPath);
if (!Files.exists(directory)) { if (!Files.exists(directory)) {
log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath); log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath);
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.usedSize(0L) .usedSize(0L)
.usedSizeFormatted("0 B") .usedSizeFormatted("0 B")
.totalDiskSpace(0L) .totalDiskSpace(0L)
.totalDiskSpaceFormatted("0 B") .totalDiskSpaceFormatted("0 B")
.freeSpace(0L) .freeSpace(0L)
.freeSpaceFormatted("0 B") .freeSpaceFormatted("0 B")
.usableSpace(0L) .usableSpace(0L)
.usableSpaceFormatted("0 B") .usableSpaceFormatted("0 B")
.usagePercentage(0.0) .usagePercentage(0.0)
.build(); .build();
} }
if (!Files.isDirectory(directory)) { if (!Files.isDirectory(directory)) {
log.debug("디렉토리 경로가 아닙니다: {}", directoryPath); log.debug("디렉토리 경로가 아닙니다: {}", directoryPath);
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.usedSize(0L) .usedSize(0L)
.usedSizeFormatted("0 B") .usedSizeFormatted("0 B")
.totalDiskSpace(0L) .totalDiskSpace(0L)
.totalDiskSpaceFormatted("0 B") .totalDiskSpaceFormatted("0 B")
.freeSpace(0L) .freeSpace(0L)
.freeSpaceFormatted("0 B") .freeSpaceFormatted("0 B")
.usableSpace(0L) .usableSpace(0L)
.usableSpaceFormatted("0 B") .usableSpaceFormatted("0 B")
.usagePercentage(0.0) .usagePercentage(0.0)
.build(); .build();
} }
// 디렉토리 사용량 계산 (재귀적으로 모든 파일 크기 합산) // 디렉토리 사용량 계산 (재귀적으로 모든 파일 크기 합산)
@@ -619,39 +622,39 @@ public class FileManagerService {
try { try {
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
usedSize[0] += attrs.size(); usedSize[0] += attrs.size();
fileCount[0]++; fileCount[0]++;
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@Override @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) { if (!dir.equals(directory)) {
directoryCount[0]++; directoryCount[0]++;
}
return FileVisitResult.CONTINUE;
} }
}); return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) { } catch (IOException e) {
log.debug("디렉토리 용량 계산 중 오류 발생: {}", directoryPath, e); log.debug("디렉토리 용량 계산 중 오류 발생: {}", directoryPath, e);
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.usedSize(0L) .usedSize(0L)
.usedSizeFormatted("0 B") .usedSizeFormatted("0 B")
.totalDiskSpace(0L) .totalDiskSpace(0L)
.totalDiskSpaceFormatted("0 B") .totalDiskSpaceFormatted("0 B")
.freeSpace(0L) .freeSpace(0L)
.freeSpaceFormatted("0 B") .freeSpaceFormatted("0 B")
.usableSpace(0L) .usableSpace(0L)
.usableSpaceFormatted("0 B") .usableSpaceFormatted("0 B")
.usagePercentage(0.0) .usagePercentage(0.0)
.build(); .build();
} }
// 디스크 공간 정보 조회 (FileStore 사용) // 디스크 공간 정보 조회 (FileStore 사용)
@@ -677,18 +680,18 @@ public class FileManagerService {
} }
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(fileCount[0]) .fileCount(fileCount[0])
.directoryCount(directoryCount[0]) .directoryCount(directoryCount[0])
.usedSize(usedSize[0]) .usedSize(usedSize[0])
.usedSizeFormatted(formatFileSize(usedSize[0])) .usedSizeFormatted(formatFileSize(usedSize[0]))
.totalDiskSpace(totalDiskSpace) .totalDiskSpace(totalDiskSpace)
.totalDiskSpaceFormatted(formatFileSize(totalDiskSpace)) .totalDiskSpaceFormatted(formatFileSize(totalDiskSpace))
.freeSpace(freeSpace) .freeSpace(freeSpace)
.freeSpaceFormatted(formatFileSize(freeSpace)) .freeSpaceFormatted(formatFileSize(freeSpace))
.usableSpace(usableSpace) .usableSpace(usableSpace)
.usableSpaceFormatted(formatFileSize(usableSpace)) .usableSpaceFormatted(formatFileSize(usableSpace))
.usagePercentage(Math.round(usagePercentage * 100.0) / 100.0) .usagePercentage(Math.round(usagePercentage * 100.0) / 100.0)
.build(); .build();
} }
} }