[SP-pm] Write Binary!
Igor Sutton Lopes
igor.sutton em gmail.com
Quinta Abril 26 09:19:15 PDT 2007
On Apr 26, 2007, at 4:43 PM, Henrique Rennó wrote:
> Fala Fred!
>
> Existe um programa muito usado aqui no trabalho chamado GrADS.
> Basicamente ele é um plotador, um gerador de gráficos. Para ele
> plotar os gráficos, os valores a serem trabalhados devem estar em
> um arquivo no formato binário (existem outros formatos que ele lê
> também mas binário é o mais geral).
>
> Os programas que faço para trabalhar com esses dados estão todos em
> C que passei dos que estavam em FORTRAN. No FORTRAN deve-se abrir o
> arquivo passando parâmetros tipo 'stream' and 'unformatted', sem
> esses parâmetros não dá certo. Já em C seria apenas a opção "b"
> para o fopen. Para escrever no arquivo, em FORTRAN usa-se o write
> passando para ele um vetor(M*N) onde N é o número de elementos da
> matriz de 2 dimensões com M linhas e N colunas na ordem linha 1,
> colunas 1-N, linha2, colunas 1-N, ..., linhaM, colunas 1-N, etc. Em
> C não dá certo usando o fscanf ou qualquer outra função que utiliza
> formatação, já o fwrite funciona como eu havia descrito antes:
> fwrite(matriz, sizeof(float), M*N, fpointer)
>
> Agora estou querendo passar para perl apenas por aprendizado.
> Tentei o pack com formatação "B*" como o Luis Motta disse e não
> funcionou.
>
Vamos lá, você quer armazenar um array mais ou menos assim:
@data = (
[ 0, 1, 2, 3, 4 ], # linha1
[ 0, 1, 2, 3, 4 ], # linha2
[ 0, 1, 2, 3, 4 ], # linhaN
);
em formato binário, certo?
Segundo a página manual do fwrite(3):
[snip]
size_t
fwrite(const void * restrict ptr, size_t size, size_t nmemb,
FILE * restrict stream);
[snip]
The function fwrite() writes nmemb objects, each size bytes
long, to the
stream pointed to by stream, obtaining them from the location
given by
ptr.
Acredito que uma primeira tentativa seria:
<code>
use strict;
use warnings;
my @data = (
[ 0, 1, 2, 3, 4 ], # linha1
[ 0, 1, 2, 3, 4 ], # linha2
[ 0, 1, 2, 3, 4 ], # linhaN
);
my $binary_data;
for my $line (@data) {
# cria o pattern para o pack, baseado no numero
# de elementos que este possui. perldoc -f pack para
# significado de "f"
my $pack_pattern = "f" x scalar @{$line};
# armazena o resultado do pack aplicado ao
# pattern acima, utilizando os elementos da
# linha
$binary_data .= pack( $pack_pattern, @$line );
}
open my $fh, ">", "/tmp/output.bin" or die $!;
binmode($fh);
print $fh $binary_data;
close $fh or warn $!;
</code>
Veja se serve prá alguma coisa, ou chega perto :-)
--
Igor Sutton
igor.sutton em gmail.com
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: http://mail.pm.org/pipermail/saopaulo-pm/attachments/20070426/cea95fd8/attachment.html
-------------- Próxima Parte ----------
Um anexo não texto foi limpo...
Nome : PGP.sig
Tipo : application/pgp-signature
Tam : 186 bytes
Descr.: This is a digitally signed message part
Url : http://mail.pm.org/pipermail/saopaulo-pm/attachments/20070426/cea95fd8/attachment.bin
Mais detalhes sobre a lista de discussão SaoPaulo-pm