Читайте и Запись в том же файле с другим процессом

Я записал две программы. Одна программа является записью содержание к текстовому файлу одновременно. Другая программа прочитана то содержание одновременно.

Но оба программа должны работать одновременно. Для меня программа является записью, которая файл правильно. Но другая программа не прочитана файл.

Я знаю, что, после того как процесс записи завершается, чем только данные будут храниться в жестком диске. Затем другой процесс может считать данные.

Но я хочу и чтение и запись то же время с другим процессом в единственном файле. Как я могу сделать это?

Пожалуйста, помогите мне. Следующий код пишет содержание в файле

sub generate_random_string
{
    my $length_of_randomstring=shift;# the length of 
       # the random string to generate

    my @chars=('a'..'z','A'..'Z','0'..'9','_');
    my $random_string;
    foreach (1..$length_of_randomstring)
    {
        # rand @chars will generate a random 
        # number between 0 and scalar @chars
        $random_string.=$chars[rand @chars];
    }
    return $random_string;
}
#Generate the random string
open (FH,">>file.txt")or die "Can't Open";
while(1)
{
my $random_string=&generate_random_string(20);
sleep(1);
#print $random_string."\n";
print FH $random_string."\n";
}

Следующий код прочитан содержание. Это - другой процесс

 open (FH,"<file.txt") or die "Can't Open";
              print "Open the file Successfully\n\n";
              while(<FH>)
              {
                  print "$_\n";
              }
5
задан muruga 11 May 2010 в 11:08
поделиться

3 ответа

у вас windows или * nix? вы могли бы связать что-то подобное вместе в * nix, используя tail, чтобы получить вывод, как он записан в файл. В Windows вы можете вызвать CreateFile () с FILE_SHARE_READ и / или FILE_SHARE_WRITE, чтобы позволить другим получить доступ к файлу, пока он открыт для чтения / записи. вам, возможно, придется периодически проверять, изменился ли размер файла, чтобы знать, когда читать (я не уверен на 100% здесь).

другой вариант - файл с отображением в память.

-1
ответ дан 14 December 2019 в 13:29
поделиться

Это работает.

Автор:

use IO::File ();

sub generate_random_string {...}; # same as above

my $file_name = 'file.txt';
my $handle = IO::File->new($file_name, 'a');
die "Could not append to $file_name: $!" unless $handle;
$handle->autoflush(1);

while (1) {
    $handle->say(generate_random_string(20));
}

Читатель:

use IO::File qw();

my $file_name = 'file.txt';
my $handle = IO::File->new($file_name, 'r');
die "Could not read $file_name: $!" unless $handle;

STDOUT->autoflush(1);
while (defined (my $line = $handle->getline)) {
    STDOUT->print($line);
}
3
ответ дан 14 December 2019 в 13:29
поделиться

Вы можете использовать сложную кооперацию протокол, такой как в следующем. Оба конца, читатель и писатель , используют общий код в модуле TakeTurns , который обрабатывает суетливые детали, такие как блокировка и расположение файла блокировки. Клиентам нужно только указать, что они хотят делать, когда у них есть монопольный доступ к файлу.

читатель

#! /usr/bin/perl

use warnings;
use strict;

use TakeTurns;

my $runs = 0;
reader "file.txt" =>
       sub {
         my($fh) = @_;
         my @lines = <$fh>;
         print map "got: $_", @lines;
         ++$runs <= 10;
       };

писатель

#! /usr/bin/perl

use warnings;
use strict;

use TakeTurns;

my $n = 10;
my @chars = ('a'..'z','A'..'Z','0'..'9','_');

writer "file.txt" =>
       sub { my($fh) = @_;
             print $fh join("" => map $chars[rand @chars], 1..$n), "\n"
               or warn "$0: print: $!";
           };

Модуль TakeTurns - это выполнение в работе:

package TakeTurns;                               

use warnings;                                    
use strict;                                      

use Exporter 'import';                           
use Fcntl qw/ :DEFAULT :flock /;                 

our @EXPORT = qw/ reader writer /;               
my $LOCKFILE = "/tmp/taketurns.lock";            

sub _loop ($&) {
  my($path,$action) = @_;
  while (1) {
    sysopen my $lock, $LOCKFILE, O_RDWR|O_CREAT
                                   or die "sysopen: $!";
    flock $lock, LOCK_EX           or die "flock: $!";
    my $continue = $action->();
    close $lock                    or die "close: $!";
    return unless $continue;
    sleep 0;
  }
}

sub writer {
  my($path,$w) = @_;
  _loop $path =>
        sub {
          open my $fh, ">", $path   or die "open $path: $!";
          my $continue = $w->($fh);
          close $fh                 or die "close $path: $!";
          $continue;
        };
}

sub reader {
  my($path,$r) = @_;
  _loop $path =>
        sub {
          open my $fh, "<", $path        or die "open $path: $!";
          my $continue = $r->($fh);
          close $fh                      or die "close $path: $!";
          $continue;
        };
}

1;

Пример вывода:

got: 1Upem0iSfY
got: qAALqegWS5
got: 88RayL3XZw
got: NRB7POLdu6
got: IfqC8XeWN6
got: mgeA6sNEpY
got: 2TeiF5sDqy
got: S2ksYEkXsJ
got: zToPYkGPJ5
got: 6VXu6ut1Tq
got: ex0wYvp9Y8

Даже несмотря на то, что у вас было столько проблем , есть еще вопросы. Протокол ненадежен, поэтому считыватель не имеет гарантии увидеть все сообщения, которые отправляет средство записи . Если писатель не активен, читатель довольствуется тем, что читает одно и то же сообщение снова и снова.

Вы можете добавить все это, но более разумным подходом было бы использование абстракций, которые уже предоставляет операционная система.

Например, именованные каналы Unix кажутся довольно близкими к тому, что вы хотите, и обратите внимание, насколько прост код:

pread

#! /usr/bin/perl

use warnings;
use strict;

my $pipe = "/tmp/mypipe";
system "mknod $pipe p 2>/dev/null";

open my $fh, "<", $pipe or die "$0: open $pipe: $!";

while (<$fh>) {
  print "got: $_";
  sleep 0;
}

pwrite

#! /usr/bin/perl

use warnings;
use strict;

my $pipe = "/tmp/mypipe";
system "mknod $pipe p 2>/dev/null";

open my $fh, ">", $pipe or die "$0: open $pipe: $!";

my $n = 10;
my @chars = ('a'..'z','A'..'Z','0'..'9','_');

while (1) {
  print $fh join("" => map $chars[rand @chars], 1..$n), "\n"
    or warn "$0: print: $!";
}

Оба конца пытаются выполнить создайте канал с помощью mknod , потому что у них нет другого метода синхронизации. По крайней мере, один выйдет из строя, но нам все равно, пока существует канал.

Как видите, все ожидающие механизмы обрабатываются системой, поэтому вы делаете то, что вам небезразлично: читаете и пишете сообщения.

4
ответ дан 14 December 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: