perl समय पर्ल में फ़ाइल खोलने और पढ़ने का सबसे अच्छा तरीका क्या है?




विदेश में पढाई कैसे करे (10)

कृपया ध्यान दें - मैं फ़ाइल खोलने / पढ़ने के लिए "सही" तरीका नहीं ढूंढ रहा हूं, या जिस तरह से मुझे हर बार फ़ाइल खोलना / पढ़ना चाहिए। मुझे यह जानने में दिलचस्पी है कि ज्यादातर लोग किस तरह से उपयोग करते हैं, और शायद एक ही समय में कुछ नए तरीकों को सीख सकते हैं:) *

मेरे पर्ल कार्यक्रमों में कोड का एक बहुत ही आम ब्लॉक फ़ाइल खोल रहा है और इसे पढ़ रहा है या लिख ​​रहा है। मैंने ऐसा करने के कई तरीके देखे हैं, और इस काम को करने पर मेरी शैली कुछ वर्षों से बदल गई है। मैं बस सोच रहा हूं कि सबसे अच्छा क्या है (यदि कोई बेहतरीन तरीका है) विधि यह है?

मैं इस तरह की एक फाइल खोलता था:

my $input_file = "/path/to/my/file";
open INPUT_FILE, "<$input_file"  || die "Can't open $input_file: $!\n";

लेकिन मुझे लगता है कि त्रुटि फंसाने में समस्याएं हैं।

एक कोष्ठक जोड़ना त्रुटि फँसाने को ठीक करने लगता है:

open (INPUT_FILE, "<$input_file")  || die "Can't open $input_file: $!\n";

मुझे पता है कि आप एक चर के लिए एक फ़ाइल हैंडल भी असाइन कर सकते हैं, इसलिए मैंने ऊपर दिए गए "INPUT_FILE" का उपयोग करने के बजाय, मैं $ input_filehandle का उपयोग कर सकता था - क्या यह तरीका बेहतर है?

फ़ाइल पढ़ने के लिए, यदि यह छोटा है, तो क्या ग्लोबिंग के साथ कुछ गलत है, इस तरह?

my @array = <INPUT_FILE>;

या

my $file_contents = join( "\n", <INPUT_FILE> );

या आप हमेशा इस तरह से लूप करना चाहिए:

my @array;
while (<INPUT_FILE>) {
  push(@array, $_);
}

मुझे पता है कि पर्ल में चीजों को पूरा करने के कई तरीके हैं, मैं बस सोच रहा हूं कि फ़ाइल में खोलने और पढ़ने के पसंदीदा / मानक तरीके हैं या नहीं?


यदि आप पूरी फ़ाइल को एक स्ट्रिंग के रूप में चाहते हैं, तो इसके माध्यम से पुन: प्रयास करने की आवश्यकता नहीं है।

use strict;
use warnings;
use Carp;
use English qw( -no_match_vars );
my $data = q{};
{
   local $RS = undef; # This makes it just read the whole thing,
   my $fh;
   croak "Can't open $input_file: $!\n" if not open $fh, '<', $input_file;
   $data = <$fh>;
   croak 'Some Error During Close :/ ' if not close $fh;
}

उपरोक्त perlcritic --brutal संतुष्ट perlcritic --brutal , जो 'सर्वोत्तम प्रथाओं' के परीक्षण के लिए एक अच्छा तरीका है :)। $input_file अभी भी अपरिभाषित है, लेकिन शेष कोशेर है।


यह सच है कि पर्ल में फ़ाइल खोलने के कई बेहतरीन तरीके हैं

$files_in_the_known_universe * $perl_programmers

... लेकिन यह देखना अभी भी दिलचस्प है कि यह आमतौर पर किस तरह से करता है। स्लरपिंग का मेरा पसंदीदा रूप (एक बार में पूरी फाइल पढ़ना) है:

use strict;
use warnings;

use IO::File;

my $file = shift @ARGV or die "what file?";

my $fh = IO::File->new( $file, '<' ) or die "$file: $!";
my $data = do { local $/; <$fh> };
$fh->close();

# If you didn't just run out of memory, you have:
printf "%d characters (possibly bytes)\n", length($data);

और जब लाइन-दर-रेखा जा रही है:

my $fh = IO::File->new( $file, '<' ) or die "$file: $!";
while ( my $line = <$fh> ) {
    print "Better than cat: $line";
}
$fh->close();

कैविट लेक्टर कोर्स: ये केवल वे दृष्टिकोण हैं जिन्हें मैंने रोजमर्रा के काम के लिए मांसपेशी स्मृति के लिए प्रतिबद्ध किया है, और वे उस समस्या के लिए मूल रूप से अनुपयुक्त हो सकते हैं, जिसे आप हल करने का प्रयास कर रहे हैं।


मैंने एक बार इस्तेमाल किया

open (FILEIN, "<", $inputfile) or die "...";
my @FileContents = <FILEIN>;
close FILEIN;

बॉयलरप्लेट नियमित रूप से। आजकल, मैं छोटी फ़ाइलों के लिए File::Slurp उपयोग करता हूं, जिसे मैं पूरी तरह से स्मृति में रखना चाहता हूं, और Tie::File बड़ी फ़ाइलों के लिए Tie::File जिन्हें मैं स्केलेबल रूप से संबोधित करना चाहता हूं और / या उन फ़ाइलों को जिन्हें मैं स्थानांतरित करना चाहता हूं।


|| ऑपरेटर की उच्च प्राथमिकता है, इसलिए इसका परिणाम "खुले" में भेजने से पहले मूल्यांकन किया जाता है ... आपके द्वारा उल्लिखित कोड में, "या" ऑपरेटर का उपयोग करें, और आपको वह समस्या नहीं होगी।

open INPUT_FILE, "<$input_file"
  or die "Can't open $input_file: $!\n";

फ़ाइल खोलने और पढ़ने का कोई अच्छा तरीका नहीं है। पूछना गलत सवाल है। फाइल में क्या है? किसी भी समय आपको कितना डेटा चाहिए? क्या आपको एक ही समय में सभी डेटा चाहिए? डेटा के साथ आपको क्या करने की ज़रूरत है? फ़ाइल को खोलने और पढ़ने की आवश्यकता के बारे में सोचने से पहले आपको उनको समझने की आवश्यकता है।

क्या आप अब कुछ भी कर रहे हैं जो आपको समस्याएं पैदा कर रहा है? यदि नहीं, तो क्या आपको हल करने में बेहतर समस्याएं नहीं हैं? :)

आपका अधिकांश प्रश्न केवल वाक्यविन्यास है, और इसका उत्तर पर्ल प्रलेखन (विशेष रूप से ( perlopentut ) में दिया गया है। आप लर्निंग पर्ल चुनना भी पसंद कर सकते हैं, जो आपके प्रश्न में आपकी अधिकांश समस्याओं का उत्तर देता है।

सौभाग्य, :)


ओओ के लिए, मुझे पसंद है:

use FileHandle;
...
my $handle = FileHandle->new( "< $file_to_read" );
croak( "Could not open '$file_to_read'" ) unless $handle;
...
my $line1 = <$handle>;
my $line2 = $handle->getline;
my @lines = $handle->getlines;
$handle->close;

डेमियन Conway इस तरह से करता है:

$data = readline!open(!((*{!$_},$/)=\$_)) for "filename";

लेकिन मैं आपको यह सलाह नहीं देता हूं।


यदि ये कार्यक्रम सिर्फ आपकी उत्पादकता के लिए हैं, जो कुछ भी काम करता है! जैसा कि आपको लगता है कि आपको आवश्यकता है उतनी त्रुटि प्रबंधन में बनाएं।

पूरी फाइल में पढ़ना अगर यह बड़ा हो तो चीजों को करने के लिए सबसे अच्छा तरीका नहीं हो सकता है, इसलिए आप लाइनों को संसाधित करना चाहेंगे क्योंकि वे उन्हें सरणी में लोड करने के बजाय आते हैं।

द प्रोगैमैटिक प्रोग्रामर (हंट एंड थॉमस) में अध्यायों में से एक से मुझे मिली एक युक्ति यह है कि आप स्क्रिप्ट स्लाईसिंग और डाइसिंग पर जाने से पहले स्क्रिप्ट को आपके लिए फ़ाइल का बैकअप सहेजना चाहेंगे।


यदि आपकी फाइलें इतनी छोटी हैं कि पूरी चीज को स्मृति में पढ़ना संभव है, तो File::Slurp उपयोग File::Slurp । यह एक बहुत ही सरल एपीआई के साथ पूर्ण फाइलें पढ़ता है और लिखता है, साथ ही यह सभी त्रुटि जांच करता है ताकि आपको यह नहीं करना पड़े।


कोई सार्वभौमिक मानदंड नहीं है, लेकिन एक या दूसरे को प्राथमिकता देने के कारण हैं। मेरा पसंदीदा रूप यह है:

open( my $input_fh, "<", $input_file ) || die "Can't open $input_file: $!";

कारण हैं:

  • आप तुरंत त्रुटियों की रिपोर्ट करते हैं। (यदि आप चाहते हैं तो "चेतावनी" के साथ "मरें" को बदलें।)
  • आपका फ़ाइलहेडल अब संदर्भित है, इसलिए एक बार जब आप इसका उपयोग नहीं कर रहे हैं तो यह स्वचालित रूप से बंद हो जाएगा। यदि आप वैश्विक नाम INPUT_FILEHANDLE का उपयोग करते हैं, तो आपको फ़ाइल को मैन्युअल रूप से बंद करना होगा या प्रोग्राम समाप्त होने तक यह खुला रहेगा।
  • रीड-मोड सूचक "<" को $ input_file से अलग किया जाता है, जो पठनीयता में वृद्धि करता है।

फ़ाइल बहुत छोटी है और आप जानते हैं कि आप सभी लाइनों को चाहते हैं:

my @lines = <$input_fh>;

यदि आप एक ही स्ट्रिंग के रूप में सभी लाइनों को संसाधित करने की आवश्यकता है, तो आप यह भी कर सकते हैं:

my $text = join('', <$input_fh>);

लंबी फ़ाइलों के लिए आप समय के साथ लाइनों पर फिर से शुरू करना चाहते हैं, या पढ़ने का उपयोग करें।





perl-io