Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Storing Info in a text File

by turnstep (Parson)
on Mar 11, 2001 at 09:07 UTC ( [id://63586]=note: print w/replies, xml ) Need Help??


in reply to Storing Info in a text File

Here's another way, featuring flock. It finds the first "unused" number when adding a new user, so the gaps are kept to a minimum.

#!/usr/bin/perl -- -*-fundamental-*- use strict; use Fcntl qw(:flock); my $type = shift or die "Need a type!\n"; my $title = shift or die "Need a title or user!\n"; my $desc = shift || ""; my $flatfile = "members.txt"; ## Format of file: ID|Title|Description &AddUser if $type =~ /add/i; &DeleteUser if $type =~ /delete/i; die qq[Invalid type of "$type"!\n]; exit; sub AddUser() { ## Add a new user to the flat file ## Open the file in read/write mode: open(FF, "+< $flatfile") or die "Could not open $flatfile: $!\n"; ## Now we lock it so nobody else messes with it until we're done flock(FF, LOCK_EX) or die "Could not flock $flatfile: $!\n"; ## Now, we read through until we find a "free" number my $goodnumber=0; my $newnumber; my $slurp=""; while(<FF>) { $goodnumber++; ($newnumber) = split(/|/, $_, 2); if ($newnumber != $goodnumber) { ## We have just skipped a number - the perfect place ## to add a new user! ## Decrease goodnumber temporarily $goodnumber--; ## Save this spot, so we can go back to it quickly ## We need to subtract the line we just read in, ## because the new entry must go *before* it my $position = tell(FF) - length $_; ## Save the current line, since we have already read it: $slurp = $_; ## Now we slurp the rest of the file into memory: ## Setting $/ allows us to read the whole thing at once ## by setting the input record separator ($/) to ## nothing. See perlvar for more. { local $/; $slurp .= <FF>; } ## Now we rewind the file back to where we marked it: seek(FF,$position,0); ## This bails us out of the while loop last; } } ## Increment (needed in case no "holes" found before the end of the +file) $goodnumber++; ## Some systems need this to switch from read to write: seek(FF,0,1); ## Add the new entry: print FF "$goodnumber|$title|$desc\n"; ## Add all the entries after that: print FF $slurp; ## We should not need to truncate, as the size is always ## increasing when adding a user, but just for fun: truncate(FF, tell(FF)); ## Close and unlock close(FF); print "Added user $goodnumber to $flatfile.\n"; exit; } ## end of AddUser sub DeleteUser() { ## Delete a user from the flat file ## What number user do we want? my $baduser = $title; ## Sanity check: $baduser =~ /^\d+$/ or die "User to delete must be a number!\n"; ## Open the file in read/write mode: open(FF, "+< $flatfile") or die "Could not open $flatfile: $!\n"; ## Now we lock it so nobody else messes with it until we're done flock(FF, LOCK_EX) or die "Could not flock $flatfile: $!\n"; ## Now, we read through until we find the "bad" number my $newnumber; my $slurp=""; while(<FF>) { ($newnumber) = split(/|/, $_, 2); if ($newnumber == $baduser) { ## Save the spot right before this user, so we can ## go back to it quickly later: my $position = tell(FF) - length $_; ## Now we slurp the rest of the file into memory: ## Setting $/ allows us to read the whole thing at once ## by setting the input record separator ($/) to ## nothing. See perlvar for more. { local $/; $slurp = <FF>; } ## Now we rewind the file back to where we marked it: seek(FF,$position,0); ## This bails us out of the while loop last; } } ## Some systems need this to switch from read to write: seek(FF,0,1); ## Add all the entries after the bad one: print FF $slurp; ## We do need to truncate, as the file size has shrunk: truncate(FF, tell(FF)); ## Close and unlock close(FF); if ($slurp) { print "Deleted user $baduser from $flatfile.\n"; } else { print "User $baduser not found in $flatfile.\n"; } exit; } ## end of DeleteUser

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://63586]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-19 13:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found