Home > Archive > PerlTk > November 2004 > Using fileevent to read a file
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Using fileevent to read a file
|
|
| Johnny Google 2004-11-07, 3:56 pm |
| Can I use fileevent to read a file I am using as a named pipe?
Does it matter if the file is already readable before the call to
fileevent? Or must the file not be readable before - and then when it
becomes readable - the specified subroutine will then be called?
I believe I am doing something wrong because the routine is never
called even though the file I intend to read is being filled by
commands by the other application.... I can refresh the file in my
editor and see the lines in the file being populated -- yet I never see
a call to the routine I specify in fileevent to read the line in the
file.
Am I using this command correctly? Hmmm?
Does someone have an example of doing exactly this? The docs and
examples I see seem to be reading filehandles that are really tied
either to sockets or output of a command. I acutally want to just read
a file as it fills up (written to by another application).
John
| |
| Johnny Google 2004-11-07, 8:56 pm |
| I build this test script to illustrate how I am attempting to implement
fileevent.
If you run this script as it is now - type a message in the writer and
click the button.
It will write the message to a file.
The reader will then read the file and display the message.
At the suggestion of others on this list, the current method of using a
repeat call to my
reader functioin would be best if replaced using fileevent however if
you uncomment my
implementation of fileevent in the script and re-run it - it will not
work.
-------------------------------------------------------------------------------
# test_pipereader.pl
# test 2 ways of reading from file
use strict;
use Tk;
use FileHandle;
use File::Slurp;
use Tk::Button;
$|=1;
my $lastline = 0;
my $pipe_in = "C:\\temp\\mypipe.dat";
my ($PIPE,%GUI,$t,$t2);
&open_pipe;
&build_gui;
# --------- I can't get this to work! -------------
#
#$GUI{mw2}->fileevent($PIPE,'readable',\&pipe_in);
# --------- This works just fine! ------------------
# -- in this example - but I think the repeate causes
# -- problems in my real perl apps and would like to
# -- replace this with the above fileevent function
my $mw2_pipe_id = $GUI{mw2}->repeat(500,sub{&pipe_in});
MainLoop;
# --------------------------------------------- #
# --------------------------------------------- #
# --------------------------------------------- #
# --------------------------------------------- #
sub open_pipe {
write_file($pipe_in,"");
$PIPE = new FileHandle;
$PIPE->open("< $pipe_in")
or die "Can't open file $pipe_in";
} # end sub
sub build_gui {
$GUI{mw} = new MainWindow;
$GUI{mw2} = new MainWindow;
$GUI{sw} = $GUI{mw}->screenwidth;
$GUI{sh} = $GUI{mw}->screenheight;
$GUI{mw_width} = int($GUI{sw}*.25);
$GUI{mw_height}= int($GUI{sh}*.25);
$GUI{mw_left} = int(($GUI{sw} - $GUI{mw_width})/4);
$GUI{mw_top} = int(($GUI{sh} - $GUI{mw_height})/4);
$GUI{mw2_left} = int(($GUI{sw} - $GUI{mw_width})/1.5);
$GUI{mw2_top} = int(($GUI{sh} - $GUI{mw_height})/4);
$GUI{mw}->geometry($GUI{mw_width}."x".$GUI{mw_height}.
"+".$GUI{mw_left}."+".$GUI{mw_top});
$GUI{mw2}->geometry($GUI{mw_width}."x".$GUI{mw_height}.
"+".$GUI{mw2_left}."+".$GUI{mw2_top});
$GUI{mw}->title("Test writer");
$GUI{mw2}->title("Test reader");
$t=$GUI{mw}->Scrolled('Text',
-width =>100,
-height =>100,
)->pack(-expand=>1,-fill=>'both');
$t2=$GUI{mw2}->Scrolled('ROText',
-width =>$GUI{mw_width},
-height =>$GUI{mw_height}*.80,
)->pack;
$t->Button(
-text=>'Write to file',
-width=>10,
-command => sub {&pipe_out},
)->pack(-side=>'bottom');
} # end sub
sub pipe_out {
my $nextline = ($lastline+1).'.0';
my $message = $t->get($nextline,'end');
append_file($pipe_in,$message);
$lastline++;
} # end sub
sub pipe_in {
#print "Checking the file $pipe_in\n";
my $message = "";
$message = $PIPE->getline;
$t2->insert("0.0",$message);
} # end sub
__END__
| |
| Ala Qumsieh 2004-11-07, 8:56 pm |
| Johnny Google wrote:
> Can I use fileevent to read a file I am using as a named pipe?
What you are really looking for is how to 'tail a file'.
The following example is courtesy of Steve Lidie:
#!/usr/local/bin/perl -w
#
# tktail pathname
use English;
use Tk;
open(H, "tail -f -n 25 $ARGV[0]|") or die "Nope: $OS_ERROR";
$mw = MainWindow->new;
$t = $mw->Text(-width => 80, -height => 25, -wrap => 'none');
$t->pack(-expand => 1);
$mw->fileevent(H, 'readable', [\&fill_text_widget, $t]);
MainLoop;
sub fill_text_widget {
my($widget) = @ARG;
$ARG = <H>;
$widget->insert('end', $ARG);
$widget->yview('end');
} # end fill_text_widget
__END__
If your OS does not include the 'tail' command, then you can replace it
with the combination of tie() and File::Tail (available from CPAN) as
described in the File::Tail docs:
use File::Tail;
my $ref=tie *H,"File::Tail",(name=>$name);
$mw->fileevent(H, 'readable', [\&fill_text_widget, $t]);
HTH,
--Ala
| |
| Johnny Google 2004-11-08, 3:58 am |
| Ala,
That sounds like it will work for me and what I am trying to do ... so
I downloaded File::Tail and it fails on nmake test
I have be trying to update the test scripts ( I did find a change -- to
modify mv to move for Win32).. but it is still failing the tests --
which is probably why it is failing in my code as well.
Know of anyone with luck getting File::Tail working on Win32?
Thanks,
John
| |
| Ala Qumsieh 2004-11-08, 3:59 pm |
| Johnny Google wrote:
> Know of anyone with luck getting File::Tail working on Win32?
Try using ppm:
ppm install File::Tail
--Ala
| |
| Johnny Google 2004-11-08, 8:58 pm |
| I tried .... this is what I get....
C:\Temp\perl\bin>ppm install File::Tail
Searching for 'File::Tail' returned no results. Try a broader search
first.
C:\Temp\perl\bin>
Is there a specific repository I need to get this particular module
from activestate?
| |
| Johnny Google 2004-11-08, 8:58 pm |
| According to activestate - this page in particular -
http://ppm.activestate.com/BuildStatus/5.8-F.html
File::Tail fails for windows -- just as I am seeing!
Any other modules which do this same thinig that are known to work on
Win32?
Any other options?
BTW, I current am doing this by reading from <PIPE> after opening it --
and using repeat
to repeatadly check the file contents --
Do you think that if I were to implement a Tail/fileevent solution that
it would solve the
issue of short freezes or overall better performance for both the Tk
gui portion and the communication
portion?
Thanks,
John
|
|
|
|
|