Adds some more IO Helpers
This commit is contained in:
parent
8e888cba1f
commit
6555b6c8f0
5 changed files with 260 additions and 3 deletions
|
@ -4,7 +4,7 @@ rm -rf doc
|
||||||
dart doc
|
dart doc
|
||||||
mkdir out
|
mkdir out
|
||||||
rm -rf out/*
|
rm -rf out/*
|
||||||
flutter pub publish -f --skip-validation
|
|
||||||
dart compile exe -o out/server_test bin/server_test.dart
|
dart compile exe -o out/server_test bin/server_test.dart
|
||||||
dart compile exe -o out/client_test bin/client_test.dart
|
dart compile exe -o out/client_test bin/client_test.dart
|
||||||
dart compile exe -o out/dbikc.bin bin/dbikc.dart
|
dart compile exe -o out/dbikc.bin bin/dbikc.dart
|
||||||
|
dart compile exe -o out/mkfsreport.bin bin/mkfsreport.dart
|
|
@ -2,6 +2,8 @@ import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:libac_dart/consts.dart';
|
||||||
|
|
||||||
class PathHelper {
|
class PathHelper {
|
||||||
String pth = "";
|
String pth = "";
|
||||||
PathHelper({required this.pth});
|
PathHelper({required this.pth});
|
||||||
|
@ -122,3 +124,220 @@ void tailAndPrint(File file) {
|
||||||
});
|
});
|
||||||
} catch (E) {}
|
} catch (E) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FileInformationCache {
|
||||||
|
static FileInformationCache? _inst;
|
||||||
|
FileInformationCache._();
|
||||||
|
|
||||||
|
Map<String, FileInfo> _registry = {};
|
||||||
|
|
||||||
|
factory FileInformationCache.obtain() {
|
||||||
|
if (_inst == null) _inst = FileInformationCache._();
|
||||||
|
|
||||||
|
return _inst!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Flushes the cache and clears it
|
||||||
|
static void flush() {
|
||||||
|
FileInformationCache.obtain()._registry.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds the specified file's information to the cache
|
||||||
|
void addFile(String path, FileInfo info) {
|
||||||
|
_registry[path] = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> generateHTMLReport(
|
||||||
|
{bool ascending = false, String VERSION = ""}) async {
|
||||||
|
String header = '''
|
||||||
|
<html>
|
||||||
|
<title>MKFSReport</title>
|
||||||
|
<body style="background-color: black;color: #00D2FA">
|
||||||
|
<h2>File System Report</h2><br/>
|
||||||
|
<b>Generated by mkfsreport v${VERSION}</b><br/>
|
||||||
|
<b>Bundled <a href="https://git.zontreck.com/AriasCreations/LibAC-dart">LibAC</a> Version: ${Constants.VERSION}</b><br/>
|
||||||
|
<pre style="color: #7a0c17">
|
||||||
|
MKFSREPORT and LibAC are provided free of charge with no implied warranties. The software is provided as-is.
|
||||||
|
|
||||||
|
This program was created by Tara Piccari, as a part of the Aria's Creations common code library as a helper utility.
|
||||||
|
Aria's Creations is a alias for online-only works. Aria is an anagram derived from my name. piccARI, tarA. You place my last name first, take the last 3, skip the first 3 in my first name and take the remaining character(s) and you have my alias.
|
||||||
|
|
||||||
|
This utility analyzed the specified folder path to generate a detailed report of directory and file sizes as seen below.
|
||||||
|
</pre><br/>
|
||||||
|
''';
|
||||||
|
|
||||||
|
header += '''
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Path</th>
|
||||||
|
<th>Size</th>
|
||||||
|
</tr>
|
||||||
|
''';
|
||||||
|
|
||||||
|
for (var entry in (await getOrderedList(ascending: ascending))) {
|
||||||
|
header += '''
|
||||||
|
<tr>
|
||||||
|
<td>${entry.isFile ? "FILE" : "DIR"}</td>
|
||||||
|
<td>${entry.path}</td>
|
||||||
|
<td>${entry.toString()}</td>
|
||||||
|
</tr>
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
|
||||||
|
header += '''
|
||||||
|
</table>
|
||||||
|
''';
|
||||||
|
|
||||||
|
header += '''
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
''';
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<FileInfo>> getOrderedList({bool ascending = false}) async {
|
||||||
|
List<FileInfo> infoList = [];
|
||||||
|
for (var entry in _registry.entries) {
|
||||||
|
infoList.add(entry.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascending)
|
||||||
|
infoList.sort((A, B) => A.size.compareTo(B.size));
|
||||||
|
else
|
||||||
|
infoList.sort((A, B) => B.size.compareTo(A.size));
|
||||||
|
|
||||||
|
return infoList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileInfo {
|
||||||
|
String path;
|
||||||
|
int size;
|
||||||
|
bool isFile;
|
||||||
|
|
||||||
|
FileInfo({required this.path, required this.size, required this.isFile});
|
||||||
|
|
||||||
|
double kb() {
|
||||||
|
return (size / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
double mb() {
|
||||||
|
return (kb() / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
double gb() {
|
||||||
|
return (mb() / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
double tb() {
|
||||||
|
return (gb() / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
if (tb() > 0.5)
|
||||||
|
return "${tb()} TB";
|
||||||
|
else if (gb() > 0.5)
|
||||||
|
return "${gb()} GB";
|
||||||
|
else if (mb() > 0.5)
|
||||||
|
return "${mb()} MB";
|
||||||
|
else if (kb() > 0.5)
|
||||||
|
return "${kb()} KB";
|
||||||
|
else
|
||||||
|
return "$size bytes";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This automatically picks TB, GB, MB, KB, or bytes depending on which returns larger than 0.5
|
||||||
|
///
|
||||||
|
/// This provides no way to know what it returns, if you need to know, use the toString method, or the individual functions to get various size types
|
||||||
|
double getSize() {
|
||||||
|
if (tb() > 0.5)
|
||||||
|
return tb();
|
||||||
|
else if (gb() > 0.5)
|
||||||
|
return gb();
|
||||||
|
else if (mb() > 0.5)
|
||||||
|
return mb();
|
||||||
|
else if (kb() > 0.5)
|
||||||
|
return kb();
|
||||||
|
else
|
||||||
|
return size.toDouble();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getFileSize(String path,
|
||||||
|
{bool cacheSize = false, bool verbose = false}) async {
|
||||||
|
if (verbose) prnt("> Checking size of file $path\r");
|
||||||
|
/*final fileBytes = await File(path).readAsBytes();
|
||||||
|
int size = fileBytes.lengthInBytes;*/
|
||||||
|
final size = await File(path).length();
|
||||||
|
|
||||||
|
if (verbose) prnt(">> Size of file $path is $size bytes\r");
|
||||||
|
|
||||||
|
if (cacheSize) {
|
||||||
|
FileInformationCache FIC = FileInformationCache.obtain();
|
||||||
|
FIC.addFile(path, FileInfo(path: path, size: size, isFile: true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getDirectorySize(String path,
|
||||||
|
{bool recursive = false,
|
||||||
|
bool cacheSize = false,
|
||||||
|
bool verbose = false}) async {
|
||||||
|
int totalSize = 0;
|
||||||
|
if (verbose) prnt("> Check dir size of $path\r");
|
||||||
|
final entityList = await Directory(path)
|
||||||
|
.list(recursive: recursive, followLinks: true)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
await Future.forEach(entityList, (entity) async {
|
||||||
|
if (entity is File) {
|
||||||
|
totalSize += await getFileSize(entity.path,
|
||||||
|
cacheSize: cacheSize, verbose: verbose);
|
||||||
|
} else if (entity is Directory) {
|
||||||
|
totalSize += await getDirectorySize(entity.path,
|
||||||
|
recursive: true, cacheSize: cacheSize, verbose: verbose);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (verbose) prnt(">> Size of dir $path is $totalSize bytes\r");
|
||||||
|
|
||||||
|
if (cacheSize) {
|
||||||
|
FileInformationCache FIC = FileInformationCache.obtain();
|
||||||
|
FileInfo FI = FileInfo(path: path, size: totalSize, isFile: false);
|
||||||
|
FIC.addFile(path, FI);
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prnt(String text) {
|
||||||
|
// Convert the string to a list of runes to handle escape sequences properly.
|
||||||
|
final runes = text.runes.toList();
|
||||||
|
|
||||||
|
for (var i = 0; i < runes.length; i++) {
|
||||||
|
final char = runes[i];
|
||||||
|
|
||||||
|
// Check for escape sequences
|
||||||
|
if (char == 0x5C && i + 1 < runes.length) {
|
||||||
|
// '\\' character in UTF-16
|
||||||
|
final nextChar = runes[i + 1];
|
||||||
|
if (nextChar == 0x72) {
|
||||||
|
// 'r' character in UTF-16
|
||||||
|
// Handle '\r' escape sequence
|
||||||
|
stdout.write('\r'); // Move the cursor back to the beginning of the line
|
||||||
|
stdout.write(
|
||||||
|
' ' * stdout.terminalColumns); // Erase the entire line with spaces
|
||||||
|
stdout.write(
|
||||||
|
'\r'); // Move the cursor back to the start of the line again after clearing
|
||||||
|
i++; // Skip the 'r' character
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the character as-is
|
||||||
|
stdout.write(String.fromCharCode(char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
6
publish.sh
Normal file
6
publish.sh
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
./compile.sh
|
||||||
|
|
||||||
|
flutter pub publish -f --skip-validation
|
|
@ -1,6 +1,6 @@
|
||||||
name: libac_dart
|
name: libac_dart
|
||||||
description: "Aria's Creations code library"
|
description: "Aria's Creations code library"
|
||||||
version: 1.2.082324+0758
|
version: 1.2.082324+2223
|
||||||
homepage: "https://zontreck.com"
|
homepage: "https://zontreck.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
32
test/io_test.dart
Normal file
32
test/io_test.dart
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import 'package:libac_dart/utils/IOTools.dart';
|
||||||
|
import 'package:test/expect.dart';
|
||||||
|
import 'package:test/scaffolding.dart';
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
test("Test file size checking", () async {
|
||||||
|
expect(await getFileSize("test/hello_world.nbt"), 33);
|
||||||
|
expect(await getFileSize("test/bigtest.nbt"), 507);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Test directory size checking", () async {
|
||||||
|
expect(await getDirectorySize("test"), 9046);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Test file info methods", () async {
|
||||||
|
FileInfo fi = FileInfo(path: "C:\\test.txt", size: 4096, isFile: true);
|
||||||
|
expect(fi.toString(), "4.0 KB");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Test ordered file info lists", () async {
|
||||||
|
await getDirectorySize("test", cacheSize: true);
|
||||||
|
FileInformationCache FIC = FileInformationCache.obtain();
|
||||||
|
var list = await FIC.getOrderedList(ascending: false);
|
||||||
|
var ascList = await FIC.getOrderedList(ascending: true);
|
||||||
|
|
||||||
|
print(list);
|
||||||
|
print(ascList);
|
||||||
|
|
||||||
|
expect(list[0].size > ascList[0].size, true);
|
||||||
|
expect(list[list.length - 1].size == ascList[0].size, true);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue