Perl—一种只从另一个目录获取第一个(.txt)文件名而不加载所有文件名的方法



我有一个存放约5000个2,400个大小的。txt文件的目录。

我只想要那个目录中的一个文件名;顺序不重要

文件将被处理并删除。

这不是脚本的工作目录

目的是:

  • 打开该文件,
  • 读,
  • 做一些事情,
  • 取消链接,然后
  • 循环到下一个文件。

我的粗略尝试并不只检查.txt文件,而且还必须为一个文件名获取所有~5000个文件名。我也可能调用太多的模块?

Verify_Empty子旨在验证有一个目录,其中有文件,但是,我的尝试失败了,所以,在这里我正在寻求帮助。

#!/usr/bin/perl -w
use strict;
use warnings;
use CGI;
use CGI ':standard';
print CGI::header();
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
###
use vars qw(@Files $TheFile $PathToFile);
my $ListFolder = CGI::param('openthisfolder');
Get_File($ListFolder);
###
sub Get_File{
  $ListFolder = shift;
  unless (Verify_Empty($ListFolder)) {
    opendir(DIR,$ListFolder);
    @Files = grep { $_ ne '.' && $_ ne '..' } readdir(DIR);
    closedir(DIR);
    foreach(@Files){
      $TheFile = $_;
    }
    #### This is where I go off to process and unlink file (sub not here) ####
    $PathToFile = $ListFolder.'/'.$TheFile;
    OpenFileReadPrepare($PathToFile); 
    #### After unlinked, the OpenFileReadPrepare sub loops back to this script. 
  }
  else {
    print qq~No more files to process~;
    exit;
  }
  exit;
}
    ####
sub Verify_Empty {
  $ListFolder = shift;
  opendir(DIR, $ListFolder) or die "Not a directory";
  return scalar(grep { $_ ne "." && $_ ne ".." } readdir(DIR)) == 0;
  closedir(DIR);
}

显然我是新手。这种方法似乎相当"饿"?似乎很多抓一个文件名和处理它!指导是伟大的!

EDIT -Latest Attempt

my $dir = '..';
my @files = glob "$dir/*.txt";
for (0..$#files){
$files[$_] =~ s/.txt$//;
}
my $PathAndFile =$files[0].'.txt';
print qq~$PathAndFile~;

这"工作",但是,它仍然得到所有的文件名。到目前为止,这里没有一个例子对我有用。我想我今天就这样过下去直到我想明白为止。也许我会再看一遍,看看有没有人能想出更好的办法。

可以在while循环中使用readdir进行循环。这样,readdir就不会返回所有文件,而每次只返回一个文件

# opendir(DIR, ...);
my $first_file = "";
while (my $file = readdir(DIR)) {
  next if $file eq "." or $file eq "..";
  $first_file = $file;
  last;
}
print "$first_filen"; # first file in directory

在列表上下文中调用readdir,它返回所有目录条目。在标量上下文中调用它:

my $file;
while( my $entry = readdir DIR ) {
    $file = $entry, last if $entry =~ /.txt$/;        
}
if ( defined $file ) {
    print "found $filen";
    # process....
}

另外,读取目录两次;一次查看它是否有任何条目,然后处理它。你真的不需要看目录是否为空;

除非我弄错了,否则您想要的只是遍历目录中的文件,所有这些关于"第一个或最后一个"one_answers"顺序无关紧要"的问题以及删除文件只是对如何做到这一点感到困惑。

那么,让我用一种非常简单的方式来表达它,看看它是否真的达到了你的目的:

my $directory = "somedir";
for my $file (<$directory/*.txt>) {
    # do stuff with the files
}

glob将做与*nix shell相同的事情,它将列出.txt扩展名的文件。如果您想对循环中的文件做进一步的测试,那是完全可以的。

缺点是在内存中保留5000个文件名,而且如果处理这个文件列表需要时间,它有可能与访问这些文件的其他进程冲突。

另一种方法是在while循环中使用readdir简单地读取文件,例如在他的回答中提到的mpapec。这样做的好处是,每次读取一个新文件名时,该文件都会在那里。此外,您不必在内存中保留一个大的文件列表。

相关内容

最新更新