J'ai un fichier binaire qui peut faire plusieurs Go à parser.
Je le lis avec read par bloc. Mon problème est que un motif peut être à cheval sur 2 blocs. Je penssais utiliser une sorte de fifo de taille double du buffer pour faire ça. Mais je me demande si il n'y a pas de manière plus "idiomatique".
# meuh
Posté par gc (site web personnel) . Évalué à 2.
[^] # Re: meuh
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
Le type de code que l'on retrouverait dans un programme d'un bon codeur perl.
J'ai un peu peur en fait que lancer une regex sur une fifo de taille double soit un peu lent :/
"La première sécurité est la liberté"
[^] # Re: meuh
Posté par gc (site web personnel) . Évalué à 3.
open F, '</tmp/track01.cdda.wav' or die "open: $!\n";
my ($buf, $prev);
while (1) {
my $ret = read F, $buf, 4096;
if (!defined($ret)) {
die "read: $!\n"
} elsif (!$ret) {
last;
} else {
if ("$prev$buf" =~ /(gc\w\w)/) {
print "match: $1\n";
}
$prev = $buf;
}
}
mais y'a sûrement pire.
[^] # Re: meuh
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
"La première sécurité est la liberté"
[^] # Re: meuh
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
/(\x1A\xCF\xFC\x1D(.|\x00){2000,2100})(?=\x1A\xCF\xFC\x1D)/
Le truc c'est (?=...) qui n'est pas pris en compte dans le déplacement.
"La première sécurité est la liberté"
[^] # Re: meuh
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
J'ai l'impression qu'il match toujours la même trame :(
il doit y avoir un soucis avec la définition du "while (//g)"
"La première sécurité est la liberté"
# Une solution...
Posté par mac . Évalué à 3.
my ($buffer, $chunk);
my $SEPARATOR = 'X'; # C'est ton séparateur de motifs
while (read F, $chunk, 4096)
{
die "Read problem" if not defined $chunk;
last if not $chunk;
$buffer .= $chunk;
if ($buffer =~ s/^([^SEPARATOR]*)$SEPARATOR//)
{
ProcessOneFrame ($1);
}
}
die "Incomplete Frame ??" if $buffer;
P.S. il faut faire le même genre de choses pour les paquets IP fragmentés, ils peuvent arriver en plusieurs fois, et il faut donc "recoller les morceaux"
P.P.S code pas testé
[^] # Re: Une solution...
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
à la fin buffer fait une taille énorme.
j'ai toujours mon pb de relecture pour les 2ième passes :/
"La première sécurité est la liberté"
[^] # Re: Une solution...
Posté par mac . Évalué à 2.
$buffer =~ s/^([^SEPARATOR]*)$SEPARATOR//
(qu'on pourrait d'ailleurs avantageusement remplacer par :
while ($buffer =~ s/^([^SEPARATOR]*)$SEPARATOR//)
{
ProcessOneFrame ($1);
}
[^] # Re: Une solution...
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
c'est pas plutôt : "s/^([^SEPARATOR].*)$SEPARATOR//)" et c'est vrai que cela à l'avantage de bien réduire la taille buffer et d'aller plus vite j'imagine.
"La première sécurité est la liberté"
[^] # Re: Une solution...
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
"La première sécurité est la liberté"
[^] # Re: Une solution...
Posté par mac . Évalué à 3.
Le premier ^ spécifie "Début de chaine"
Les [] veulent dire "Un des caractères parmi... et le ^ dans les [] effectue une négation, donc "aucun des caractères parmi".
De façons plus générale, il est difficile (et inutile) d'expliquer ce que sont les regexp et comment elles fonctionnent dans un forum... Plutôt te renvoyer vers quelques sources d'information :
- perldoc perlrequick ou perldoc perlretut ou perldoc perlre ou encore perldoc perlreref (il faut avoir installé le package de documentation Perl qui va bien)
- l'excellent livre consacré aux regexp de chez O'Reilly http://www.oreilly.com/catalog/regex/(...)
- google
- et le sympatique Vrex qui a tout pour plaire à un débutant : http://page.sourceforge.net/vrex.html(...)
Bon courage ! (et comment as-tu pu vivre sans elles ?)
[^] # Re: Une solution...
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
"La première sécurité est la liberté"
[^] # Re: Une solution...
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
Mon délimiteur fait plusieurs caractère de long donc le "truc" [^abc] ne marche pas. Ensuite, je parse du binaire et "." ne peut pas prendre certaine valeur notement "\n", il faut rajouter /s pour cela.
Donc ma regexp est devenu :
s/(\x1a\xcf\xfc\x1d.{2000,2100})((?=\x1a\xcf\xfc\x1d)|$)//s
(?=) pour la présence du délimiteur à la fin
/s pour ne pas se faire avoir avec '.'
vala merci pour l'aide !
"La première sécurité est la liberté"
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.