If your data store is SQL92 compliant, or even if DBI is willing to think it is, this is easily accomplished with a query of the form below. I've never used them, but as I understand it, DBI has a data base driver that will read a csv file and probbaly has others for other flat file formats, including colon delimited.
my $sql = "UPDATE tablename SET bandwidth = bandwidth + ? WHERE user =
+ ?";
my $sth = $dbh->prepare($sql);
my $sth->execute($newtraffic,$user);
However, if you are reading and writing a plain text file, and don't want to wire it up through DBI, you could also grep on $user to find your line, then use something like:
my @user_fields = split /:/,$_;
$user_fields[2] = $user_fields[2] + $newtraffic;
my $newline = $user_fields[0].':'.$user_fields[1].':'.$user_fields[2];
then you can open two file handles, one for reading and one for writing, read the data from the original file, writing it to the new file, using the code above wrapped in a conditional checking for your $user (if(m/$user/){}), to massage it as it goes by.
-- Hugh
if( $lal && $lol ) { $life++; }
| [reply] [d/l] [select] |
open two file handles at the same time?
| [reply] |
Yes, two handles at once, like so:
open(DB_RESULT,">/path/to/result/db/file");
open(DB_SRC,"/path/to/source/db/file");
while (<DB_SRC>){
if($_ ~= /$user/){
my @user_fields = split /:/,$_;
$user_fields[2] = $user_fields[2] + $newtraffic;
my $newline = $user_fields[0].':'.$user_fields[1].':'.$user_fields
+[2];
print DB_RESULT, $newline;
} else {
print DB_RESULT, $_;
}
}
close(DB_SRC);
close(DB_RESULT);
my $result = `mv /path/to/result/db/file /path/to/source/db/file`;
There may be some slick way to do this with only one file open overwriting only the line you are concerned with, but it is not apparent to me at this late hour. And generally I am of the mind that it is more important to ensure that a program works than that it is fast or fancy.
if( $lal && $lol ) { $life++; }
| [reply] [d/l] |
Hello again,
i am at university right now, and for the TIE::FILE does nto work at all....
i tried..but i m not sure if its right
i will paste this code
open(data,"userlist.txt") or di
+e "$@";
while ($line = <data>)
{
@details = split(/:/,$l
+ine);
if ($name[0] eq $detail
+s[0])
{
print "check -----> $de
+tails[0] , $details[1] ,$downloadTotal \n";
open(FH, ">download
+temp.txt") or die "$@";
print "check 2 ----
+-> $details";
print(FH $downloadT
+otal);
open(FH,">>userlis
+t.txt") or die "$@";
$details[2] = $ det
+ails[2] + $downloadTotal;
$newline = $details
+[0].':'.$details[1].':'.$details[2];
print(FH $newline);
+
}
i checked the userlist.txt
its like this after this:
kevin:12345678:
dex:12345678:11955436
brandon:12345678:kevin:12345678:12348kevin:12345678:134kevin:12345678:135 | [reply] [d/l] |
| [reply] |
You should use a real database to store the userdata, as you will very likely get bitten by race conditions and locking a single line of the userlist file will not work.
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
CountZero is definitely right that using a database will be easier and more efficient than dealing with text files and locking. And remember that DB_File and DBD::SQLite count as databases, even though they don't require any kind of server.
| [reply] |