From 001a82269b0154c9f5208664c837eb7679f52b48 Mon Sep 17 00:00:00 2001 From: Sven Fillinger Date: Thu, 23 Apr 2026 10:50:59 +0200 Subject: [PATCH] feat(raw-data): Display file sizes in human-readable format - Add FileSizeFormatter utility class for byte-to-human-readable conversion - Update RawDataDetailsComponent to use formatted file sizes - Display sizes as B, KB, MB, or GB with 2 decimal precision Addresses #1405 --- .../commons/FileSizeFormatter.java | 46 +++++++++++++++++++ .../rawdata/RawDataDetailsComponent.java | 5 +- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 application-commons/src/main/java/life/qbic/application/commons/FileSizeFormatter.java diff --git a/application-commons/src/main/java/life/qbic/application/commons/FileSizeFormatter.java b/application-commons/src/main/java/life/qbic/application/commons/FileSizeFormatter.java new file mode 100644 index 0000000000..954f1b1082 --- /dev/null +++ b/application-commons/src/main/java/life/qbic/application/commons/FileSizeFormatter.java @@ -0,0 +1,46 @@ +package life.qbic.application.commons; + +import java.util.Locale; + +/** + * Utility class for formatting file sizes in human-readable format. + *

+ * Provides methods to convert byte values to human-readable strings + * using decimal (SI) units where 1 KB = 1000 B, 1 MB = 1000 KB, + * and 1 GB = 1000 MB. + */ +public class FileSizeFormatter { + + private static final long KILOBYTE = 1_000L; + private static final long MEGABYTE = 1_000_000L; + private static final long GIGABYTE = 1_000_000_000L; + + private FileSizeFormatter() { + // Utility class - no instantiation + } + + /** + * Formats a byte value into a human-readable string. + *

+ * The value is scaled to the most appropriate decimal unit (B, KB, MB, or GB) + * and rounded to 2 decimal places. + * + * @param bytes the size in bytes + * @return a formatted string with the appropriate unit (e.g., "3.00 GB", "512.75 MB") + */ + public static String formatBytes(long bytes) { + if (bytes < 0) { + return "0 B"; + } + if (bytes < KILOBYTE) { + return bytes + " B"; + } + if (bytes < MEGABYTE) { + return String.format(Locale.US, "%.2f KB", bytes / (double) KILOBYTE); + } + if (bytes < GIGABYTE) { + return String.format(Locale.US, "%.2f MB", bytes / (double) MEGABYTE); + } + return String.format(Locale.US, "%.2f GB", bytes / (double) GIGABYTE); + } +} \ No newline at end of file diff --git a/datamanager-app/src/main/java/life/qbic/datamanager/views/projects/project/rawdata/RawDataDetailsComponent.java b/datamanager-app/src/main/java/life/qbic/datamanager/views/projects/project/rawdata/RawDataDetailsComponent.java index a6610cdc7e..a0430b66e8 100644 --- a/datamanager-app/src/main/java/life/qbic/datamanager/views/projects/project/rawdata/RawDataDetailsComponent.java +++ b/datamanager-app/src/main/java/life/qbic/datamanager/views/projects/project/rawdata/RawDataDetailsComponent.java @@ -26,6 +26,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import life.qbic.application.commons.FileNameFormatter; +import life.qbic.application.commons.FileSizeFormatter; import life.qbic.application.commons.time.DateTimeFormat; import life.qbic.datamanager.files.export.download.DownloadStreamProvider; import life.qbic.datamanager.files.export.rawdata.RawDataUrlFile; @@ -401,7 +402,7 @@ private ComponentRenderer renderRawDa BasicSampleInformation::sampleName).toList()); rawDataItem.addEntry("Number of Files", String.valueOf(rawData.dataset().numberOfFiles())); - rawDataItem.addEntry("File Size", String.valueOf(rawData.dataset().totalSizeBytes())); + rawDataItem.addEntry("File Size", FileSizeFormatter.formatBytes(rawData.dataset().totalSizeBytes())); rawDataItem.addListEntry("File Suffixes", rawData.dataset().fileTypes()); return rawDataItem; }); @@ -414,7 +415,7 @@ private ComponentRenderer renderRawDa BasicSampleInformation::sampleName).toList()); rawDataItem.addEntry("Number of Files", String.valueOf(rawData.dataset().numberOfFiles())); - rawDataItem.addEntry("File Size", String.valueOf(rawData.dataset().totalSizeBytes())); + rawDataItem.addEntry("File Size", FileSizeFormatter.formatBytes(rawData.dataset().totalSizeBytes())); rawDataItem.addListEntry("File Suffixes", rawData.dataset().fileTypes()); return rawDataItem; });