For Programmers: Free Programming Magazines  


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

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com