Archivos binarios: lectura, escritura
Publicado: 2017-09-23 22:27 @977
Tengo el siguiente script. Lee un archivo llamado 'log.log' y extrae datos según se cumpla la regex.
Luego, este otro para buscar un registro específico en el archivo 'index.bin' ya generado:
La regex compara si existe en el archivo 'log.log' alguna línea como:
[Tuesday, May 2, 2017] [1:21:46 AM PDT] Join Invitado-5392 ([email protected]) has joined this channel.
La 'subrutina' llamada toId() lo que hace es generar un 'id' que me sirve para mover el cursor a un punto del archivo, primero para escribir, luego para leer la posición específica.
El punto es... que no funciona: me da registros en una posición del archivo que no corresponde, siendo el que el valor que recibe para escribir es diferente del que tiene que leer.
El 'id' determina si existe un registro o no. He intentado de muchas formas antes de venir a preguntar (un valor de bytes constante en la funciona seek y read, usar length, etc.) pero nada funciona, en lenguaje C usando el mismo método (o al menos parecido) funciona, es decir, fseek(*FILE,(cursor * sizeof(struct), SEEK_SET);
¿Alguno sabría cómo ayudarme?
Using perl Syntax Highlighting
- use Fcntl;
- use bytes;
- my $ruta = qw(/home/USER/);
- my $archivo = "log.log";
- my $regex_joinfile = '^\\[(.*)\\](\\s+)\\[(.*)\\](\\s+)Join(\\s+)(.*)(\\s+)\\((.*)@(.*)\\)(.*)$';
- my $match = 0;
- my $regs = 0;
- open my $p, sprintf("<%s/%s", $ruta, $archivo);
- open my $q, sprintf(">%s/%s", $ruta, "index.bin");
- binmode $q;
- my %hash_ips;
- while (<$p>)
- {
- chomp $p;
- if ($_ =~ $regex_joinfile)
- {
- my $seekpoint = toId($9);
- seek $q, ($seekpoint * 32), SEEK_SET;
- if (defined($hash_ips{$9}))
- {
- $hash_ips{$9} = $hash_ips{$9} + 1;
- } else {
- $hash_ips{$9} = 1;
- $regs++;
- }
- print $q $9;
- $match++;
- }
- }
- close($p);
- close($q);
- sub toId {
- my($v) = (shift);
- my @toks = split(//, $v);
- my $id;
- for(my $chr = 0; $chr < scalar(@toks); $chr++)
- {
- $id += ord($toks[$chr]);
- }
- return $id
- }
- my $diff = $match - $regs;
- print "Fin del archivo $ruta, coincidencias $match veces. registros $regs adicionados, ignorados $diff ips\n";
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Luego, este otro para buscar un registro específico en el archivo 'index.bin' ya generado:
Using perl Syntax Highlighting
- use Fcntl;
- use bytes;
- my $ruta = qw(/home/USER/);
- my $archivo = "log.log";
- my $regex_joinfile = '^\\[(.*)\\](\\s+)\\[(.*)\\](\\s+)Join(\\s+)(.*)(\\s+)\\((.*)@(.*)\\)(.*)$';
- open my $p, sprintf("<%s/%s", $ruta, $archivo);
- open my $q, sprintf("<%s/%s", $ruta, "index.bin");
- binmode $q;
- while (<$p>)
- {
- chomp $p;
- if ($_ =~ $regex_joinfile)
- {
- my $point = (toId($9) * 32);
- seek $q, $point, SEEK_SET;
- my $lectura;
- read($q, $lectura, 32);
- my $i = toId($lectura);
- my $j = toId($9);
- print "--> $lectura - $9 -- $i - $j \n";
- sleep(5);
- }
- }
- close($p);
- close($q);
- sub toId {
- my($v) = (shift);
- my @toks = split(//, $v);
- my $id;
- for(my $chr = 0; $chr < scalar(@toks); $chr++)
- {
- $id += ord($toks[$chr]);
- }
- return $id
- }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
La regex compara si existe en el archivo 'log.log' alguna línea como:
[Tuesday, May 2, 2017] [1:21:46 AM PDT] Join Invitado-5392 ([email protected]) has joined this channel.
La 'subrutina' llamada toId() lo que hace es generar un 'id' que me sirve para mover el cursor a un punto del archivo, primero para escribir, luego para leer la posición específica.
El punto es... que no funciona: me da registros en una posición del archivo que no corresponde, siendo el que el valor que recibe para escribir es diferente del que tiene que leer.
El 'id' determina si existe un registro o no. He intentado de muchas formas antes de venir a preguntar (un valor de bytes constante en la funciona seek y read, usar length, etc.) pero nada funciona, en lenguaje C usando el mismo método (o al menos parecido) funciona, es decir, fseek(*FILE,(cursor * sizeof(struct), SEEK_SET);
¿Alguno sabría cómo ayudarme?