Open File to Read from in Perl - perl

I just started learning Perl today. I'm on the section of file input and output. This is a very basic question, and I've been searching on the internet for a couple of hours as to what I'm doing wrong, but I can't seem to find out why. I'm sure some of you think this question should be voted down, but if I could find the answer by myself through internet searching and troubleshooting, I wouldn't be asking it here.
My question is why can't I open the file that I'm referring to in my filepath?
open(my $in, "<", "ioFile.txt") or die "Can't open input.txt: $!";
The ioFile.txt is in the same directory as my Perl script. I've used multiple different filepaths to see which worked, and none have for me so far. I've tried using forward slashes instead of backslashes as well.
Any tips about opening this specific file or files in general in Perl would be greatly appreciated.
After Edit:
It could be permissions on the file, but I do have read and write permissions on the file, but not full control permissions. I'm on Windows 7 btw.

If you're not running the script while you are in the directory the script and the file you want to open are in, then you have to specify the full path to the file:
open my $in, '<', 'c:\path\to\ioFile.txt' or die "Can't open input.txt: $!";
perl will look for the input file from the location you are running the script from, not in the directory the script is in (again, unless you are in that directory when you are running the script).

Related

Failing to open Excel files for writing

I am using open to write data into an Excel file. This is working fine with .txt files, but with .xls files it always fails.
This is the code I am writing
$filename = "abc.xls";
$fhandle = "ABC";
open( $fhandle, ">$filename" ) || die "cannot open file $filename";
The same code executes fine in another environment which has an older Perl version.
I need help on how can I fix this.
Found the problem to the issue. The environment I was trying to create these files in already had the files with the same name but did not have permissions for me to edit those files. I deleted the old files and it worked like a charm.
Thanks a lot for your help guys.!!
Shivam
A file handle is a file handle. Not a string.
Also, you are typing the filename in the open call. Why don't you use the $filename variable you so neatly created two lines earlier?
I would try something like this:
$filename = "abc.xls";
open($fhandle, ">$filename") || die "cannot open file $filename";
Also, this xls file: Is it open in excel when you try to run the script? Excel will stop you from opening it in another application or script if you do.
Furthermore : Please use strict and warnings. They will make your life much better.

Unable to Downsample audio file in CGI perl script using sox

I am working on a cgi script where I get an uploaded an audio file, downsample it to 8000Hz and then get it recognised later.
I am facing an error while downsampling the file. The code for downsampling goes like:
1) Code for File Upload:
use CGI;
use strict;
use File::Copy qw(copy);
use CGI::Carp 'fatalsToBrowser';
my $PROGNAME = "file_upload.cgi";
my $cgi = new CGI();
print "Content-type: text/html\n\n";
my $upfile = $cgi->param('upfile');
# Get the basename in case we want to use it.
my $basename = GetBasename($upfile);
no strict 'refs';
if (! open(OUTFILE, ">../cgi-bin/upload/".$basename) ) {
print "Can't open for writing - $!";
exit(-1);
}
2)Code for downsample:
my $source_file="/var/www/cgi-bin/upload/$upfile";
system("sox $source_file -r 8000 /var/www/cgi-bin/upload/temp.wav".";"."mv /var/www/cgi-bin/upload/temp.wav $source_file");
where:
source_file is the path for uploaded audio file
$upfile is the name of the uploaded wav file
temp.wav is the temporary downsampled file which is overwritten on the original file using mv command
Error
sox FAIL formats: can't open input file `/var/www/cgi-bin/upload/file1.wav': WAVE: RIFF header not found
file1.wav is the file I uploaded
Please help me understand why the sox command is not executing despite it being correctly written?
This isn't really an answer to your question as we don't have enough information yet.
Have you tried running the command from your Unix command line? I'd assume you get the same error. What do you get if you run file on the file that you have saved? How big is the file before and after you upload it?
You don't show the code that writes the uploaded file. I suspect there's a bug in that. If you add that to your question, we could help you find it.
Where is GetBasename() defined? Can we see the code?
Your sox command seems strange. You're running sox on a file called temp.wav and then copying that file over your uploaded file. Perhaps there are a couple of steps that you aren't telling us.
Some other suggestions for improvement:
Use cgi->new, not new CGI. The latter has some strange corner cases that you will have real problems debugging if you ever come across them.
If you're loading the CGI module, then why not use its header method instead of writing your own (technically incorrect) header.
no strict 'refs' is a really bad idea (and, as far as I can see, isn't needed here).
Please use the three-arg version of open() and lexical filehandles
open my $out_fh, '>', "../cgi-bin/upload/$basename"
Include the file path in your error message
my $file = "../cgi-bin/upload/$basename";
if (!open my $out_fh, '>', $file) {
print "Can't open file '$file' for writing - $!";
exit(-1);
}
You are loading the File::Copy module, but then moving your file using a shell command.
Allowing random users to upload files into a directory under your cgi-bin directory is a massive potential security hole. You should find another directory to store the uploaded files.
Oh, and then there's the whole - why on Earth would you be writing CGI programs in 2017!
The issue is resolved. The reason why I was having problem executing the sox and copy commands was because of where I was placing the two commands in code. Basically a beginners error. So I was opening the file as mentioned in the problem statement. I put the copy and sox commands for execution before I closed the filehandler and hence they were not getting executed successfully.

Open filehandle not working under mod_perl ModPerl::PerlRun

I'm at my first attempt to use mod_perl. I'm totally new to it. I opted for ModPerl::PerlRun because I don't want to make any modification to the scripts I already have
I followed the instructions in Installing Apache2/Modperl on Ubuntu 12.04
I uploaded script.pl to /perl, and the script looks like it's running fine except for this
open(my $fh, '<:encoding(UTF-8)', 'page_template.htm') or die $!;
It won't open the file and dies with the message
No such file or directory at /var/www/perl/script.pl
Update
Note that the documentation for ModPerl::PerlRun has this to say
META: document that for now we don't chdir() into the script's dir, because it affects the whole process under threads.
so it is probably not workable to simply do a chdir in your program's code, and the second option below should be used
Original*
The current working directory of your CGI program isn't what you think. It is most likely to tbe the root directory /
You can either use chdir to set the working directory of the script
use File::Basename 'dirname';
chdir dirname(__FILE__);
or simply add the full path to the name of the file that you want to open, for instance
open my $fh, '<:encoding(UTF-8)', '/perl/page_template.htm' or die $!;
Note that you can't use FindBin, as your program is being run as a subroutine of Apache's main mod_perl process, so $FindBin::Bin will be equal to the directory of the Apache executable httpd and not of your own program file

How to open multiple files in Perl

Guys im really confused now. Im new to learning Perl. The book ive read sometimes do Perl codes and sometimes do Linux commands.
Is there any connection between them? (Perl codes and linux commands)
I want to open multiple files using Perl code, i know how to open a single file in Perl using:
open (MYFILE,'somefileshere');
and i know how to view multiple files in Linux using ls command.
So how to do this? can i use ls in perl? And i want to open certain files only (perl files) which dont have file extension visible (I cant use *.txt or etc. i guess)
A little help guys
Use system function to execute linux command, glob - for get list of files.
http://perldoc.perl.org/functions/system.html
http://perldoc.perl.org/functions/glob.html
Like:
my #files = glob("*.h *.m"); # matches all files with a .h or .m extension
system("touch a.txt"); # linux command "touch a.txt"
Directory handles are also quite nice, particularly for iterating over all the files in a directory. Example:
opendir(my $directory_handle, "/path/to/directory/") or die "Unable to open directory: $!";
while (my $file_name = <$directory_handle>) {
next if $file_name =~ /some_pattern/; # Skip files matching pattern
open (my $file_handle, '>', $file_name) or warn "Could not open file '$file_name': $!";
# Write something to $file_name. See <code>perldoc -f open</code>.
close $file_handle;
}
closedir $directory_handle;

Perl to set a directory to open, open it, then print the directory opened?

Trying to troubleshoot a port of some perl code from CentOS to Windows.
Really know nothing about Perl, and the code I'm porting is around 700-1000 lines. 100% sure one of the issues I'm seeing is related to how the code is being rendered as a result of being on the OS it's running on.
So, I'm looking for a way to troubleshoot debugging how the OS's are rendering filepath apart from the legacy code; which I can not post to SO due to "IP" reasons.
So, I looking for some perl that I can set a directory to open within the script (for example, C:\data\ or /home/data), then script attempts to load the directory, prints if it failed or succeeded, and then prints the string it attempted to load, regardless if the code failed to open the directory or not.
Open to suggestions, but that's the issue, and the solution I'm seeing.
Questions, feedback, requests - just comment, thanks!!
use IO::Dir;
my $dir = IO::Dir->new($dir_path) or
die "Could not open directory $dir_path: $!\n";
of course, where $dir_path is some path to a directory on your system that you want, either as a var or hard coded. The more 'old school' way would look like:
opendir my $dir, $dir_path or die "Could not open directory $dir_path: $!\n";
That won't print of the directory is opened, but the program will fail if it doesn't open it then print the precise error as to why, which is what the $! variable holds.
Is this what you're looking for?
use DirHandle;
my $dir = "test";
my $dh = new DirHandle($dir);
if($dh) {
print "open directory succeeded\n";
}
else {
print "open directory failed\n";
}
print $dir, "\n";
new DirHandle opens the directory and returns a handle to it. The handle will be undef if the open failed.