I've been putting together a custom folder class and came across this post. In Powershell, how do I sort a Collections.Generic.List of DirectoryInfo?
The folder class is meant to have a sort function that sorts by Length a List of [FileInfo] Objects.
The both classes compile without errors.
But the List of FileInfo Objects does not seem to sort from largest to smallest. Does anybody have an idea why my sort function does not seem to sort?
Custom Comparer Class
class Comparer : System.Collections.Generic.IComparer[System.IO.FileInfo] {
[int]Compare([System.IO.FileInfo]$a, [System.IO.FileInfo]$b)
{
if($a.Length -eq $b.Length)
{
$res = 0
}
elseif($a.Length -lt $b.Length)
{
$res = -1
}
else
{
$res = 1
}
return $res
}
}
Custom Folder Class
class Folder {
[System.IO.DirectoryInfo]$Root
[System.Collections.Generic.List[System.IO.FileInfo]]$Files
[int]$Size
Folder([System.String]$Path){
$this.Root = [System.IO.DirectoryInfo]::new($Path)
}
[void]GetFiles([String[]]$Query){
$this.Files = [System.Collections.Generic.List[System.IO.FileInfo]]::new()
ForEach($Q in $Query){
try {
$local:Archivos = $this.Root.EnumerateFiles($Q, "AllDirectories")
foreach($Archivo in $Archivos){
$File= [System.IO.FileInfo]::new($Archivo.FullName)
$this.Files.Add($File)
}
}
catch [System.Management.Automation.MethodInvocationException]{
if($_.FullyQualifiedErrorID -eq "FileNotFoundException"){
[System.Console]::WriteLine($_.Exception.Message)
}
}
}
}
[void]ListFiles(){
[System.Console]::WriteLine("[Root] $($this.Root.FullName)")
foreach($File in $this.Files){
[System.Console]::WriteLine("`t[$($this.FormatSize($File.Length))] $($File.Name)")
}
}
[void]SortFiles() {
$local:Comparer = [Comparer]::new()
$this.Files.Sort($local:Comparer)
}
[void]DeleteFiles(){
foreach($File in $this.Files){
$File.Delete()
}
}
[void]GetSize(){
[System.Int64]$this.Size = 0
foreach($File in $this.Files){
$this.Size += $File.Length
}
}
[System.String]FormatSize([System.Int64]$Size){
$local:Formatato = ""
switch ($Size) {
{$Size -lt 1099511627776}{
$Formatato = "$([System.Math]::Round(($Size/1GB), 2))GB"
}
{$Size -lt 1073741824}{
$Formatato = "$([System.Math]::Round(($Size/1MB), 2))MB"
}
{$Size -lt 1048576}{
$Formatato = "$([System.Math]::Round(($Size/1KB), 2))KB"
}
Default {
$Formatato = "$([System.Math]::Round(($Size), 2))B"
}
}
return $local:Formatato
}
}
Test of Classes in action
$Downloads = [Folder]::new($Path)
$Downloads.GetFiles("*")
$Downloads.SortFiles()
$Downloads.ListFiles()
[Root] C:\Users\charles.murray\Downloads
[0.6KB] index.html.example
[0.91KB] prometheus.yml
[1.3KB] prometheus.html
[1.42KB] node.html
[2.61KB] node-cpu.html
[2.82KB] menu.lib
[3.44KB] node-disk.html
[3.68KB] NOTICE
[4.01KB] prometheus-overview.html
[6.01KB] prom.lib
[19.53KB] queries.active
[73.48KB] rufus.log
[896KB] 00000000
[8.72MB] MS108EUP_V1.0.1.9-runtime.image
[108.23MB] promtool.exe
[114.81MB] prometheus.exe
[128MB] 000001
$Downloads.Files
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/17/2023 2:01 PM 616 index.html.example
-a---- 7/17/2023 2:00 PM 934 prometheus.yml
-a---- 8/4/2023 11:31 PM 1114 MS108EUP_V1.0.1.9_Release_Notes.html
-a---- 7/17/2023 2:01 PM 1334 prometheus.html
-a---- 7/17/2023 2:01 PM 1453 node.html
-a---- 7/17/2023 2:01 PM 2675 node-cpu.html
-a---- 7/17/2023 2:01 PM 2888 menu.lib
-a---- 7/17/2023 2:01 PM 3522 node-disk.html
-a---- 7/17/2023 2:00 PM 3773 NOTICE
-a---- 7/17/2023 2:01 PM 4103 prometheus-overview.html
-a---- 7/17/2023 2:01 PM 5783 node-overview.html
-a---- 7/17/2023 2:01 PM 6152 prom.lib
-a---- 7/17/2023 2:00 PM 11357 LICENSE
-a---- 7/17/2023 2:01 PM 20001 queries.active
-a---- 7/26/2023 11:57 AM 75243 rufus.log
-a---- 7/17/2023 3:11 PM 917504 00000000
-a---- 8/4/2023 11:31 PM 9143718 MS108EUP_V1.0.1.9-runtime.image
-a---- 7/17/2023 2:01 PM 113488896 promtool.exe
-a---- 7/17/2023 2:00 PM 120385536 prometheus.exe
-a---- 7/17/2023 3:11 PM 134217728 000001
Change your
Compare
method, it can be greatly simplified:Then descending sorting works properly:
For ascending order you would be using:
As aside, I would recommend you to add a constructor that takes a comparer and add the comparer as a property of your class, then you could add an ascending and descending method without having to instantiate a new comparer: