Правильный способ чтения файла данных в массив - PullRequest
27 голосов
/ 22 января 2012

У меня есть файл данных, в каждой строке которого есть одно число, например

10
20
30
40

Как мне прочитать этот файл и сохранить данные в массиве?

Чтобы я мог выполнить некоторые операции с этим массивом.

Ответы [ 6 ]

73 голосов
/ 22 января 2012

Простое чтение файла в массив, по одной строке на элемент, тривиально:

open my $handle, '<', $path_to_file;
chomp(my @lines = <$handle>);
close $handle;

Теперь строки файла находятся в массиве @lines.

Если вычтобы убедиться, что есть обработка ошибок для open и close, сделайте что-то подобное (в приведенном ниже примере мы открываем файл в режиме UTF-8 тоже):

my $handle;
unless (open $handle, "<:encoding(utf8)", $path_to_file) {
   print STDERR "Could not open file '$path_to_file': $!\n";
   # we return 'undefined', we could also 'die' or 'croak'
   return undef
}
chomp(my @lines = <$handle>);
unless (close $handle) {
   # what does it mean if close yields an error and you are just reading?
   print STDERR "Don't care error while closing '$path_to_file': $!\n";
} 
11 голосов
/ 22 января 2012

Существует самый простой способ, с использованием модуля File::Slurp:

use File::Slurp;
my @lines = read_file("filename", chomp => 1); # will chomp() each line

Если вам нужна некоторая проверка для каждой строки, вы можете использовать grep перед read_file.

Например, строки фильтра, которые содержат только целые числа:

my @lines = grep { /^\d+$/ } read_file("filename", chomp => 1);
10 голосов
/ 19 декабря 2013

Мне нравится ...

@data = `cat /var/tmp/somefile`;

Это не так гламурно, как другие, но все равно работает.И ...

$todays_data = '/var/tmp/somefile' ;
open INFILE, "$todays_data" ; 
@data = <INFILE> ; 
close INFILE ;

Ура.

1 голос
/ 28 февраля 2019
open AAAA,"/filepath/filename.txt";
my @array = <AAAA>; # read the file into an array of lines
close AAAA;
1 голос
/ 22 января 2012

Tie::File - это то, что вам нужно:

Синопсис

# This file documents Tie::File version 0.98
use Tie::File;

tie @array, 'Tie::File', 'filename' or die ...;

$array[13] = 'blah';     # line 13 of the file is now 'blah'
print $array[42];        # display line 42 of the file

$n_recs = @array;        # how many records are in the file?
$#array -= 2;            # chop two records off the end


for (@array) {
  s/PERL/Perl/g;         # Replace PERL with Perl everywhere in the file
}

# These are just like regular push, pop, unshift, shift, and splice
# Except that they modify the file in the way you would expect

push @array, new recs...;
my $r1 = pop @array;
unshift @array, new recs...;
my $r2 = shift @array;
@old_recs = splice @array, 3, 7, new recs...;

untie @array;            # all finished
0 голосов
/ 17 апреля 2019

Зависит от размера файла! Приведенные выше решения имеют тенденцию использовать удобные сокращения для копирования всего файла в память, что будет работать во многих случаях.

Для очень больших файлов вам может потребоваться использовать потоковую конструкцию, в которой файл читается построчно или в чанках, обрабатывается чанки, а затем удаляется из памяти.

Смотрите ответ на , читая построчно с perl , если это то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...