Why does readdir() list the filenames in wrong order?

781 views Asked by At

I'm using the following code to read filenames from a directory and push them onto an array:

#!/usr/bin/perl

use strict;
use warnings;

my $directory="/var/www/out-original";
my $filterstring=".csv";
my @files;
# Open the folder
opendir(DIR, $directory) or die "couldn't open $directory: $!\n";

foreach my $filename (readdir(DIR)) {
    if ($filename =~ m/$filterstring/) {
        # print $filename;
        # print "\n";
        push (@files, $filename);
    } 
}
closedir DIR;

foreach my $file (@files) {
    print $file . "\n";
}

The output I get from running this code is:

Report_10_2014.csv
Report_04_2014.csv
Report_07_2014.csv
Report_05_2014.csv
Report_02_2014.csv
Report_06_2014.csv
Report_03_2014.csv
Report_01_2014.csv
Report_08_2014.csv
Report.csv
Report_09_2014.csv

Why is this code pushing the file names into the array in this order, and not from 01 to 10?

1

There are 1 answers

3
Jonathan Cast On BEST ANSWER

Unix directories are not stored in sorted order. Unix commands like ls and sh sort directory listings for you, but Perl's opendir function does not; it returns items in the same order the kernel does, which is based on the order they're stored in. If you want the results to be sorted, you'll need to do that yourself:

for my $filename (sort readdir(DIR)) {

(Btw: bareword file handles, like DIR, are global variables; it's considered good practice to use lexical file handles instead, like:

opendir my $dir, $directory or die "Couldn't open $directory: $!\n";
for my $filename (sort readdir($dir)) {

as a safety measure.)