• Publicidad

Cadena de ruta al archivo

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Cadena de ruta al archivo

Notapor korsakof » 2017-06-21 04:03 @210

Hola.

Estoy haciendo un pequeño programa y no sé por qué cuando solicito un dato por consola me indica que no puede acceder al archivo que le indico, copiando y pegando la ruta en la consola. En cambio, cuando le indico la ruta absoluta del archivo como se muestra en el primer bloque de código, funciona.

Cabecera:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. require 'C:\Users\Paco\Desktop\Recursos\perl\libreria.pm';
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Funciona la llamada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print "\nIndica la ruta a testar:";
  2. $ruta=<STDIN>;
  3. testFile('C:\Users\Paco\Desktop\Recursos\perl\prueba.log');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

No funciona la llamada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print "\nIndica la ruta a testar:";
  2. $ruta=<STDIN>;
  3. testFile($ruta);#Este metodo se encuentra dentro de libreria.pm
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Funcion Testlib:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub testFile {
  2.     my $filename = $_[0];
  3.     open( my $fh, "<", $filename )
  4.         or die "Could not open file '$filename' $!";    #linea 520
  5.  
  6.     while ( my $row = <$fh> ) {
  7.         chomp $row;
  8.         if ( defined $row && $row ne "" ) {
  9.             test( $row, 1 );
  10.         }
  11.     }
  12. }
  13.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub testFile {
  2.     my $filename = shift @_;
  3.     print "\nFilename=>$filename\n";
  4.     open( my $fh, "<", $filename )
  5.         or die "Could not open file '$filename' $!";    #linea 520
  6.  
  7.     while ( my $row = <$fh> ) {
  8.         chomp $row;
  9.         if ( defined $row && $row ne "" ) {
  10.             test( $row, 1 );
  11.         }
  12.     }
  13. }
  14.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Error:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. Could not open file 'C:\Users\Paco\Desktop\Recursos\perl\prueba.log
  2. ' Invalid argument at C:\Users\Paco\Desktop\Recursos\perl\libreria.pm line 520, <STDIN> line 1.
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


No sé qué estoy haciendo mal, he comprobado la variable al llegar al método y es capaz de mostrarla pero no la procesa.

Muchas gracias. Un saludo. Sigo investigando.

Actualizo

He conseguido hacerlo funcionar pero no entiendo por qué no funcionaba.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $fh, "<$filename")
  2.   or die "Could not open file '$filename' $!";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


He probado varios que no sé por qué no funcionan, indica que es por el parámetro pero yo veo que llega bien la ruta a la función:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $fh, "<","$filename")
  2.   or die "Could not open file '$filename' $!";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $fh, '<',"$filename")
  2.   or die "Could not open file '$filename' $!";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $fh, '<','$filename')
  2.   or die "Could not open file '$filename' $!";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
korsakof
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2016-03-02 03:20 @181

Publicidad

Re: Cadena de ruta al archivo

Notapor explorer » 2017-06-21 07:05 @337

Cuando lees algo por el teclado, Perl recibe todos los caracteres MÁS los caracteres de final de línea (recuerda que has pulsado la tecla de Entrar o Enter en el teclado). Bueno, pues recibes todo eso.

Fíjate en el mensaje de error... hay un retorno de carro y un avance de línea justo después del texto prueba.log, que hace que la comilla simple aparezca en la línea siguiente.

El error está claro: el sistema no es capaz de abrir un archivo que se llama "prueba.log\n\r". Aunque tú no veas esos caracteres, el sistema sí que los ve y se cree que estás buscando algo así.

La solución es... la misma que tienes dentro de testFile(): poner un chomp() a la línea que hemos recibido del usuario:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. chomp($ruta = <STDIN>);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ahora bien... ¿por qué funciona con unos open() y con otro no?

Resulta que open(), cuando se le llama con la forma de 2 argumentos, hace una "limpieza" de los caracteres "espacio" que rodeen al nombre del archivo a abrir. Por ejemplo, estas dos líneas hacen lo correcto:

open(my $fh, "<$filename");
open(my $fh, "< $filename ");

Es más... si $filename contiene caracteres de espacio, TAMBIÉN los quita. Y eso es lo que está pasando en tu correo: Perl elimina en el open() los caracteres de fin de línea que estaban puestos en lo que metió el usuario por teclado. La explicación es que esos caracteres de fin de línea tienen la misma consideración que los caracteres de espacio.

Pero... eso no funciona en la versión de 3 argumentos:

open(my $fh, "<", $filename);

En este caso, Perl permite $filename contenga cualquier tipo de caracteres, incluidos los finales de línea, y no los quita... y por lo tanto salta el error de que no encuentra ese archivo.

Entonces,
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $fh, "<", "$filename");  # Da lo mismo comillas dobles que simples
  2. open(my $fh, '<', "$filename");  #   alrededor de '<'.
  3. open(my $fh, '<', '$filename');  # ¡ERROR! Le estamos pidiendo que nos abra el archivo '$filename', literal
  4. open(my $fh, '<',  $filename );  # Las comillas dobles alrededor de $filename, sobran.
  5.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


La recomendación es:
  • quitar los caracteres que sobran, en el momento de la lectura (el chomp() anterior), y
  • usar la forma de 3 argumentos de open() ya que tiene un plus de seguridad (la versión de 2 argumentos tiene, además, el problema de "interpretar" caracteres de redirección, así que puede ser algo peligroso).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cadena de ruta al archivo

Notapor korsakof » 2017-07-04 03:57 @206

¡¡Muchísimas gracias!!!. Ya conseguí arreglarlo y entenderlo. La verdad es que no me había percatado de esa diferencia que comentas en el mensaje anterior.
korsakof
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2016-03-02 03:20 @181


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado