user1067305
user1067305

Reputation: 3501

In Perl, why can't I open this file using single argument open?

The file is 52MB in size. It is in the same directory as the program.

$big = 'VIXhx.csv';

# tie @optLine, 'Tie::File', $big or die "Cant Tie to $big $!" ; 

open $big or die "Cant open $big, $!," ; 

Tie::File gave no error message.

Plain open gave the error message:

Cant open VIXhx.csv, No such file or directory, at C:\Python34\hsf\ETFs\VIX\qad. pl line 47.

(Yes, it's in the Python directory - but Perl works fine there)

I can open the file in the editor, so there doesn't seem to be a problem with the file itself.

I have a smaller file in the same program that opened with no problem in Tie::File.

$dat = 'ETF5Y.csv';

tie @datLine, 'Tie::File', $dat or die "Cant Tie to $dat $!" ; 

Is it possible that Perl is unable to open a file if it's too large?

Upvotes: 0

Views: 266

Answers (3)

user1067305
user1067305

Reputation: 3501

I found the answer to my original question, of why TIE didn't work.

It turns out that the file used '0A' as the line terminator, so TIE, expecting '0D0A', read the whole 52MB file as one record.

I added recsep => "\n" to the TIE statement, and everything works fine.

Upvotes: 2

Sinan Ünür
Sinan Ünür

Reputation: 118166

See perldoc perlopentut:

Single Argument Open

Remember how we said that Perl's open took two arguments? That was a passive prevarication. You see, it can also take just one argument. If and only if the variable is a global variable, not a lexical, you can pass open just one argument, the filehandle, and it will get the path from the global scalar variable of the same name.

$FILE = "/etc/motd";
open FILE or die "can't open $FILE: $!";
while (<FILE>) {
    # whatever
}

Therefore, if you want single argument open to do what you want, you would have to write our code as

$big = 'VIXhx.csv';
open big or die "Can't open '$big': $!"; 
#   ^ <-- look, no dollar sign before filehandle

Alternatively, you could do something like this:

$big = 'VIXhx.csv';
*{$big} = \$big;
open $big and print <$big>;

if you want to keep the open $big.

But, relying on global variables and effects at a distance is not a good idea. Instead, use the three argument form of open to specify the filehandle, the mode, and the file name separately as in:

open my $vix_fh, '<', $vix_file
    or die "Failed to open '$vix_file': $!";

By the way, you won't even find this section on "Single Argument Open" in recent Perl documentation. The following note should give you and idea why:

Why is this here? Someone has to cater to the hysterical porpoises. It's something that's been in Perl since the very beginning, if not before.

The single argument open can also be used to turn any Perl program into a quine.

Upvotes: 2

mpapec
mpapec

Reputation: 50667

Please check perldoc -f open on how to open files, what you did ended up in opening an empty filename,

strace perl -e '$big = "/etc/passwd"; open $big or die "Cant open $big, $!,"'

output

...
open("", O_RDONLY)                      = -1 ENOENT (No such file or directory)
write(2, "Cant open /etc/passwd, No such f"..., 64Cant open /etc/passwd, No such file or directory, at -e line 1.

Upvotes: 2

Related Questions