Gossamer Forum
Home : General : Perl Programming :

File Control. Mental Block.

Quote Reply
File Control. Mental Block.
I've got the following code:

Code:
open (ID, "</home/fba/walesyearbook.co.uk/cgi-bin/data/orders.2002.db");
$newkey = <ID> + 1;
close ID;

open (ID2, ">/home/fba/walesyearbook.co.uk/cgi-bin/data/orders.2002.db");
print ID2 ("$newkey");
close ID2;
How can I reduce this to one file handle? I've got the developer's block ;-)

Note: What I'm trying to do is to get a number from a file, incrament the number by one, and rewrite the file data with the new number.

Cheers

Wil

- wil
Quote Reply
Re: [Wil] File Control. Mental Block. In reply to
I think you are using the best way really.

If you want one file handle you'd need +< but I don't find this very reliable

Could I ask why you have:

print ID2 ("$newkey");

Why not:

print ID2 $newkey;

?

Last edited by:

RedRum: Nov 7, 2001, 4:07 AM
Quote Reply
Re: [RedRum] File Control. Mental Block. In reply to
I've written it as ("$newkey"); because I've taken that snippet out of a longer line of code, which wrote a number of lines to a flat file, and I wanted to have a "safer" way.

So, there is no way of doing this with one file handle? Hmm. There must be?

What was that +< you were talking about?

Thanks.

- wil
Quote Reply
Re: [Wil] File Control. Mental Block. In reply to
Yes theoretically you could use one filehandle using +< eg...

open F, "+</path/to/file" or die $!;

code

close F;

+< = read/write

Last edited by:

RedRum: Nov 7, 2001, 7:18 AM
Quote Reply
Re: [RedRum] File Control. Mental Block. In reply to
Yeah, but I need the code :-)

- wil
Quote Reply
Re: [Wil] File Control. Mental Block. In reply to
It's the same as you have above except you only open/close once.

Last edited by:

RedRum: Nov 7, 2001, 7:40 AM
Quote Reply
Re: [RedRum] File Control. Mental Block. In reply to
Hmm.

Doesn't seem to work.

Wil

- wil
Quote Reply
Re: [Wil] File Control. Mental Block. In reply to
Precisely...thats why I said

Quote:
I don't find this very reliable

The way you have it is fine. It isn't going to slow your script down.

Last edited by:

RedRum: Nov 7, 2001, 8:08 AM
Quote Reply
Re: [RedRum] File Control. Mental Block. In reply to
You'd make a good second-hand car salesman, Paul! ;-)

- wil
Quote Reply
Re: [Wil] File Control. Mental Block. In reply to
+< isn't going to help you, because when you open a file like that you generally shouldn't use <FH> to read from it - instead you need to use read(), which will read a certain number of bytes from the current position. Since it looks like you are simply trying to increment a counter on the first line, the line will be variable. If you really want to do it, you'll need to do something like this:

Code:
open FH, "+<", $filename;
read FH, my $binary, 4;
my $num = unpack "l", $binary;
seek FH, 0, 0;
print FH pack "l", $num + 1;
close FH;

As you can see, it's simpler to just use two open()s. Smile

Jason Rhinelander
Gossamer Threads
jason@gossamer-threads.com
Quote Reply
Re: [jagerman] File Control. Mental Block. In reply to
Yeah, thanks Jason! I was just wondering on performance wise.

- wil
Quote Reply
Re: [Wil] File Control. Mental Block. In reply to
On a tiny file like that I think you'd be hard-pressed to find a noticeable difference. On a massive file, however, it becomes very useful.

Jason Rhinelander
Gossamer Threads
jason@gossamer-threads.com
Quote Reply
Re: [jagerman] File Control. Mental Block. In reply to
So let me get this straight...

That code reads 4 bytes into the file and converts the bytes into a list of values taking the first one. Then we go back to the beginning of the file and the code adds one to the value we obtained and re-packs it into bytes and re-prints to the file?

Am I close?

Why 4 bytes?...is that the length of a character?

Last edited by:

RedRum: Nov 8, 2001, 10:51 AM
Quote Reply
Re: [RedRum] File Control. Mental Block. In reply to
In Reply To:
Why 4 bytes?...is that the length of a character?

It's the length of a packed 32-bit integer. In this case, signed, but you could make it unsigned by change the "l" to "L" - still 4 bytes.

It's probably easier to think of the file as containing 32 bits, rather than 4 bytes. What is actually contained in the file is a binary number, which unpack converts into a decimal number, then it is incremented, then pack turns it back into binary and writes it to the file.

Jason Rhinelander
Gossamer Threads
jason@gossamer-threads.com
Quote Reply
Re: [jagerman] File Control. Mental Block. In reply to
Ahhh. So I'm guessing it would be pretty tricky with a file with more data inside?

Say....

dsadas5dasdas

..or would you use a different method for that?
Quote Reply
Re: [RedRum] File Control. Mental Block. In reply to
If your data consisted of strings, it would be pointless. But, if your data was all packed to certain lengths, this would generally be a faster (and easier) way to handle it. A text file or a file with variable length rows would become exceedingly difficult using this method, so you wouldn't use it.

Jason Rhinelander
Gossamer Threads
jason@gossamer-threads.com