By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,671 Members | 1,670 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,671 IT Pros & Developers. It's quick & easy.

Modes for opening files !?

P: 43
Hello guys,

I have not figure out how to properly use the read/write mode for opening files +>, +<, +>>

I tried it but always got unpredicatable output.

I usually do this for standard read/write operation:

Expand|Select|Wrap|Line Numbers
  1. open(NEW_DATABASE, ">$file2");
  2. open(DATABASE, "<$file1");
  3.  
  4. while (<DATABASE>) {
  5.     $line = $_;
  6.     chop $line;
  7.  
  8.     # Some operations on the line
  9.  
  10.     print NEW_DATABASE  "line\n";
  11. } # end of while (<DATABASE>)
  12.  
  13. close(DATABASE);
  14. close(NEW_DATABASE);
  15.  
  16. rename($file2, $file1);
Which work fine

Then I tried this code bellow. Not really to save 3 lines of code but to understand how to use the R/W mode...

Expand|Select|Wrap|Line Numbers
  1. open(DATABASE, "+>$file1");  
  2.  
  3. while (<DATABASE>) {
  4.     $line = $_;
  5.     chop $line;
  6.  
  7.     # Some operations on the line
  8.  
  9.     print  DATABASE  "line\n";
  10. } # end of while (<DATABASE>)
  11.  
  12. close(DATABASE);
The output was very unpredicatable. It did not do what I wanted.

Is there a way to use these read/write mode to rewrite a single line in one pass or should I stick to the first design, which work?

Thanks,

Yves

PS: I did not forgot the tag this time ;-)
Feb 18 '11 #1
Share this Question
Share on Google+
4 Replies


numberwhun
Expert Mod 2.5K+
P: 3,503
Ha ha, I noticed. Thank you! :)

For a good understanding of this topic, you may want to check out this tutorial. Hopefully it will help with your understanding.

Regards,

Jeff
Feb 18 '11 #2

miller
Expert 100+
P: 1,089
Well, to start off with I have a few thoughts/suggestions concerning your first method of translating the file:
  1. use strict;
  2. Use Lexical filehandles in three part form.
  3. Add error checking to your file open operations
  4. use chomp over chop since you're only wanting to remove return characters
  5. chomp first before assigning to a variable, just makes things simpler

Anyway, to test out the code I created the following data file called foo.dat

Expand|Select|Wrap|Line Numbers
  1. This is just testing if we can translate some numbers.
  2.  
  3. It will taking any digits like 1 2 3 and perform some
  4. operation on them.  The whole idea is that we are 
  5. just able to test out modes of reading and writing.
  6. It will ideally be a lossless translation that is also
  7. it's own inverse.
  8.  
  9. More numbers like 45 and 79 for no particular reason.
  10.  
I then came up with a translation we could do on the file. I decided on taking any digit and adding 5 to it and then modulus 10. This way all numbers will be changed back to their original value by doing the translation a second time.

Expand|Select|Wrap|Line Numbers
  1. use File::Copy qw(move);
  2.  
  3. use strict;
  4.  
  5. my $file = 'foo.dat';
  6.  
  7. my $newfile = $file . '.new';
  8.  
  9. open my $oh, '>', $newfile or die "Can't open file, $newfile: $!";
  10. open my $ih, $file or die "Can't open file, $file, $!";
  11.  
  12. while (<$ih>) {
  13.     chomp;
  14.     my $line = $_;
  15.  
  16.     #       Some operations on the line
  17.     $line =~ s/(\d)/($1 + 5) % 10/eg;
  18.  
  19.     print $oh "$line\n";
  20. }      # end of while    while (<$ih>)
  21.  
  22. close $oh;
  23. close $ih;
  24.  
  25. move($newfile, $file) or die "Can't move $newfile -> $file: $!";
  26.  
  27. 1;
  28.  
  29. __END__
Finally, the whole point of this question was that you were curious about read/write mode for open. I'd actually discourage you from using that as it's only really useful for binary files. If you want to do read/write operations on a text file then check out Tie::File, as it will do all the hard work for you.

Expand|Select|Wrap|Line Numbers
  1. use Tie::File;
  2.  
  3. use strict;
  4.  
  5. my $file = 'foo.dat';
  6.  
  7. tie my @data, "Tie::File", $file, autochomp => 0
  8.     or die "Can't open file, $file: $!";
  9.  
  10. for (@data) {
  11.     #       Some operations on the line
  12.     s{(\d)}{($1 + 5) % 10}eg;
  13. }
  14.  
  15. untie @data;
  16.  
  17. 1;
  18.  
  19. __END__
- Miller
Feb 18 '11 #3

Expert Mod 100+
P: 589
Expand|Select|Wrap|Line Numbers
  1. while (<$ih>) {
  2.     chomp;
  3.     my $line = $_;
  4.  
Is better written as:
Expand|Select|Wrap|Line Numbers
  1. while ( my $line = <$ih> ) {
  2.     chomp $line;
  3.  

And I'd also add the warnings pragma.
Expand|Select|Wrap|Line Numbers
  1. use warnings;
Feb 18 '11 #4

P: 43
Wooooow !

I think that I will stick with my original method, which is quite simple after all… and works :D

There is an American "say" I love and use all the time. It goes "if it ain't broken, don't fix it!"

Thanks guys,

Yves
Feb 18 '11 #5

Post your reply

Sign in to post your reply or Sign up for a free account.