Skip to content

6. Los archivos de texto

Un archivo de texto es un archivo que contiene líneas de texto. Veamos la creación y el uso de este tipo de archivos con algunos ejemplos.

6.1. Creación y uso

Programa
Resultados
C:\>cscript fic1.vbs

C:\>dir

FIC1     VBS           352  07/01/02   7:07 fic1.vbs
TESTFILE TXT            25  07/01/02   7:07 testfile.txt

C:\>more testfile.txt

Ceci est un autre test.

Comentarios

  • La línea 7 crea un objeto de archivo de tipo «Scripting.FileSystemObject» mediante la función CreateObject(«Scripting.FileSystemObject»). Este tipo de objeto permite acceder a cualquier archivo del sistema, no solo a archivos de texto.
  • La línea 9 crea un objeto «TextStream». La creación de este objeto está asociada a la creación del archivo testfile.txt. Este archivo no se designa con un nombre absoluto del tipo c:\dir1\dir2\....\testfile.txt, sino con un nombre relativo testfile.txt. Se creará, por tanto, en el directorio desde el que se ejecute el comando para ejecutar el archivo.
  • El sistema de archivos de Windows no distingue entre conceptos como «archivo de texto» o «archivo no de texto». Solo reconoce archivos. Por lo tanto, es el programa que utiliza este archivo el que debe determinar si lo va a tratar como un archivo de texto o no.
  • La línea 9 crea un objeto a partir del cual se utiliza el comando set para la asignación. La creación de un objeto de archivo de texto implica la creación de dos objetos:
    • la creación de un objeto Scripting.FileSystemObject (línea 7)
    • y, a continuación, la creación de un objeto «TextStream» (archivo de texto) mediante el método OpenTextFile del objeto Scripting.FileSystemObject, que admite varios parámetros:
      • el nombre del archivo a gestionar (obligatorio)
      • el modo de uso del archivo. Se trata de un entero con 3 valores posibles:
        • 1: uso del archivo en modo lectura
        • 2: uso del archivo en modo escritura. Si aún no existe y el tercer parámetro está presente y tiene el valor true, se crea; de lo contrario, no. Si ya existe, se sobrescribe.
        • 8: uso del archivo en modo de adición, c.a.d. Escritura al final del archivo. Si el archivo aún no existe y el tercer parámetro está presente y tiene el valor «true», se crea; de lo contrario, no.
  • La línea 11 escribe una línea de texto con el método WriteLine del objeto TextStream creado.
  • La línea 13 «cierra» el archivo. A partir de ese momento, ya no se puede escribir ni leer en él.
  • La línea 16 crea un nuevo objeto «TextStream» para utilizar el mismo archivo que antes, pero esta vez en modo «añadir». Las líneas que se escriban se añadirán detrás de las líneas existentes.
  • La línea 18 escribe dos nuevas líneas, sabiendo que la constante vbCRLF es el marcador de fin de línea de los archivos de texto.
  • La línea 20 vuelve a cerrar el archivo
  • la línea 23 lo vuelve a abrir en modo «lectura»: vamos a leer el contenido del archivo.
  • La línea 27 lee una línea de texto con el método ReadLine del objeto TextStream. Cuando el archivo acaba de «abrirse», nos situamos en la primera línea de texto del mismo. Una vez leída esta línea mediante el método ReadLine, nos situamos en la segunda línea. Así, el método Readline no solo lee la línea actual, sino que además «avanza» automáticamente a la siguiente línea.
  • Para procesar todas las líneas de texto, el método ReadLine debe aplicarse repetidamente en un bucle. Este bucle (línea 26) finaliza cuando el atributo AtEndOfStream del objeto TextStream tiene el valor true. Esto significa que ya no hay más líneas que leer en el archivo.

6.2. Casos de error

Se dan dos casos de error frecuentes:

  • apertura en lectura de un archivo que no existe
  • apertura en escritura o adición de un archivo que no existe con el tercer parámetro establecido en false en la llamada al método OpenTextFile.

El siguiente programa muestra cómo detectar estos errores:

Programa

' creación y rellenado de un archivo de texto
Option Explicit
Dim objFichier,MyFile
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim codeErreur

' se crea un objeto de archivo
Set objFichier=CreateObject("Scripting.FileSystemObject")

' se abre un archivo de texto que debe existir en modo de lectura
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForReading)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
     ' el archivo no existe
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
     ' se cierra el archivo de texto
    MyFile.Close
End If


' se abre un archivo de texto que debe existir en modo de escritura
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForWriting, False)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
     ' se cierra el archivo de texto
    MyFile.Close
End If

' se abre un archivo de texto que debe existir en modo de adición
On Error Resume Next
Set MyFile= objFichier.OpenTextFile("abcd", ForAppending, False)
codeErreur=err.number
On Error GoTo 0
If codeErreur<>0 Then
    wscript.echo "Le fichier [abcd] n'existe pas"
Else
     ' se cierra el archivo de texto
    MyFile.Close
End If

' fin
wscript.quit 0

Resultados

C:\>dir

FIC1     VBS           964  07/01/02   7:54 fic1.vbs
TESTFILE TXT             0  07/01/02   8:18 testfile.txt
FIC2     VBS         1 252  07/01/02   8:23 fic2.vbs
3 fichier(s)              2 216 octets
2 répertoire(s)        4 007.11 Mo libre

C:\>cscript fic2.vbs

Le fichier [abcd] n'existe pas
Le fichier [abcd] n'existe pas
Le fichier [abcd] n'existe pas

6.3. La aplicación IMPOTS con un archivo de texto

Retomamos la aplicación de cálculo de impuestos suponiendo que los datos necesarios para el cálculo se encuentran en un archivo de texto llamado data.txt:

12620 13190 15640 24740 31810 39970 48360 55790 92970 127860 151250 172040 195000 0
0 0,05 0,1 0,15 0,2 0,25 0,3 0,35 0,4 0,45 0,5 0,55 0,6 0,65
0 631 1290,5 2072,5 3309,5 4900 6898,5 9316,5 12106 16754,5 23147,5 30710 39312 49062

Las tres líneas contienen, respectivamente, los datos de las tablas límite coeffR y coeffN de la aplicación. Gracias a la modularización de nuestra aplicación, las modificaciones se producen principalmente en el procedimiento getData, encargado de construir las tres tablas. El nuevo programa es el siguiente:

Programa

' cálculo del impuesto de un contribuyente
' el programa debe ejecutarse con tres parámetros: casado, hijos, salario
' casado: carácter O si está casado, N si no lo está
' hijos: número de hijos
' salario: salario anual sin céntimos

' declaración obligatoria de las variables
Option Explicit
Dim erreur

' se recuperan los argumentos comprobando su validez
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' ¿Error?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)

' se recuperan los datos necesarios para el cálculo del impuesto
Dim limites, coeffR, coeffN
erreur=getData(limites,coeffR,coeffN)
' ¿Error?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit 5

' se muestra el resultado
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)

' salimos sin errores
wscript.quit 0

' ------------ funciones y procedimientos

' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
     ' debe recuperar tres valores pasados como argumento al programa principal
     ' un argumento se transmite al programa sin espacios delante ni detrás
     ' se utilizarán expresiones regulares para verificar la validez de los datos

     ' devuelve una variable de tipo matriz de error con 2 valores
     ' error(0): código de error, 0 si no hay error
     ' error(1): mensaje de error si hay error; de lo contrario, cadena vacía

    Dim syntaxe
    syntaxe= _
    "Syntaxe : pg marié enfants salaire" & vbCRLF & _
    "marié : caractère O si marié, N si non marié" & vbCRLF & _
    "enfants : nombre d'enfants (entier >=0)" & vbCRLF & _
    "salaire : salaire annuel sans les centimes (entier >=0)"

     ' se comprueba que haya 3 argumentos
    Dim nbArguments
    nbArguments=wscript.arguments.count
    If nbArguments<>3 Then
         ' mensaje de error
        getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
         ' fin
        Exit Function
    End If

    Dim modele, correspondances
    Set modele=new regexp

     ' el estado civil debe estar entre los caracteres oOnN
    modele.pattern="^[oOnN]$"
    Set correspondances=modele.execute(wscript.arguments(0))
    If correspondances.count=0 Then
         ' mensaje de error
        getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
         ' salimos
        Exit Function
    End If
     ' se recupera el valor
    If lcase(wscript.arguments(0)) = "o"Then
        marie=true
    Else
        marie=false
    End If

     ' hijos debe ser un número entero >=0
    modele.pattern="^\d{1,2}$"
    Set correspondances=modele.execute(wscript.arguments(1))
    If correspondances.count=0 Then
         ' error
        getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
         ' salir
        Exit Function
    End If
     ' se recupera el valor
    enfants=cint(wscript.arguments(1))

     ' el salario debe ser un número entero >=0
    modele.pattern="^\d{1,9}$"
    Set correspondances=modele.execute(wscript.arguments(2))
    If correspondances.count=0 Then
         ' error
        getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
         ' salir
        Exit Function
    End If
     ' se recupera el valor
    salaire=clng(wscript.arguments(2))

     ' se ha completado sin errores
    getArguments=array(0,"")
End Function

' ----------- getData
Function getData(byref limites, ByRef coeffR, ByRef coeffN)
     ' los datos de las tres tablas límite, coeffR, coeffN, están en un archivo de texto
     ' llamado data.txt. Cada tabla ocupa una línea con el formato val1 val2 ... valn
     ' se encuentran, en orden, los límites coeffR y coeffN

     ' devuelve una variante de tabla de error de 2 elementos para gestionar el posible error
     ' error(0): 0 si no hay error, un número entero >0 en caso contrario
    ' error(1): el mensaje de error si hay error

    Dim objFichier,MyFile,codeErreur
    Const ForReading = 1, dataFileName="data.txt"

     ' se crea un objeto de archivo
    Set objFichier=CreateObject("Scripting.FileSystemObject")
     ' se abre el archivo data.txt en modo lectura
    On Error Resume Next
    Set MyFile= objFichier.OpenTextFile(dataFileName, ForReading)
     ' ¿error?
    codeErreur=err.number
    On Error GoTo 0
    If codeErreur<>0 Then
         ' se ha producido un error; lo anotamos
        getData=array(1,"Impossible d'ouvrir le fichier des données [" & dataFileName & "] en lecture")
         ' se introduce
        Exit Function
    End If

     ' Ahora se da por hecho que el contenido es correcto y no se realiza ninguna comprobación
     ' se leen las 3 líneas

     ' límites
    Dim ligne, i
    ligne=MyFile.ReadLine
    getDataFromLine ligne,limites

     ' coeffR
    ligne=MyFile.ReadLine
    getDataFromLine ligne,coeffR


     ' coeffN
    ligne=MyFile.ReadLine
    coeffN=split(ligne," ")
    getDataFromLine ligne,coeffN

     ' se cierra el archivo
    MyFile.close

     ' se ha completado sin errores
    getData=array(0,"")
End Function

' ----------- getDataFromLine
Sub getDataFromLine(byref ligne, ByRef tableau)
     ' coloca en una tabla los valores numéricos contenidos en la línea
     ' Estos están separados por uno o varios espacios

     ' al principio, la tabla está vacía
    tableau=array()
     ' se define un modelo para la línea
    Dim modele, correspondances
    Set modele= New RegExP
    With modele
        .pattern="\d+,\d+|\d+"    ' 140,5 ou 140
        .global=true              ' toutes les valeurs
    End With

     ' se analiza la línea
    Set correspondances=modele.execute(ligne)
    Dim i
    For i=0 To correspondances.count-1
         ' se redimensiona la tabla
        ReDim Preserve tableau(i)
         ' se asigna un valor al nuevo elemento
        tableau(i)=cdbl(correspondances(i).value)
    Next

     'fin
End Sub




' ----------- calculerImpot
Function calculerImpot(byval marie,ByVal enfants,ByVal salaire, ByRef limites, ByRef coeffR, ByRef coeffN)

     ' se calcula el número de participaciones
    Dim nbParts
    If marie=true Then
        nbParts=(enfants/2)+2
    Else
        nbParts=(enfants/2)+1
    End If
    If enfants>=3 Then nbParts=nbParts+0.5

     ' se calcula el coeficiente familiar y la base imponible
    Dim revenu, qf
    revenu=0.72*salaire
    qf=revenu/nbParts

     ' se calcula el impuesto
    Dim i, impot
    i=0
    Do While i<ubound(limites) And qf>limites(i)
        i=i+1
    Loop
    calculerImpot=int(revenu*coeffr(i)-nbParts*coeffn(i))
End Function

Comentarios:

  • En el archivo de texto data.txt, los valores pueden estar separados por uno o varios espacios, por lo que no es posible utilizar la función split para extraer los valores de la línea. Ha sido necesario recurrir a una expresión regular
  • la función getData devuelve, además de las tres tablas límite, coeffR, coeffN, un resultado que indica si se ha producido un error o no. Este resultado es una variante de tabla de dos elementos. El primer elemento es un código de error (0 si no hay error), el segundo es el mensaje de error si se ha producido un error.
  • La función getData no comprueba la validez de los valores encontrados en el archivo data.txt. En una situación real, debería hacerlo.