menu
  Home  ==>  articles  ==>  colibri_helpers  ==>  u_c_text_file   

u_c_text_file - John COLIBRI.


1 - Introduction

Cet article présente une classe permettant de manipuler un fichier ASCII comme un tableau.

L'avantage de cette technique par rapport à l'emploi de fichiers .TEXT sont:

  • rapidité
  • traitement uniforme des données (pas de lecture en deux niveaux: les lignes, puis les caractères de la ligne)
  • possibilité de lire ET d'écrire
Certes les tStream offraient une autre possibilité. Elle n'a pas été retenue:
  • pour des raisons purement historiques. La manipulation de fichiers ASCII dans des tableaux en mémoire, je la pratique depuis l'Apple ][, et, toujours à court de temps, je n'ai pas modifié la technique
  • les traitements tels que les décalages de textes vers la fin du tampon (pour remplacer un mot par un mot plus long) ne sont pas à priori possibles. "Stream" dit flux, le modèle est donc l'ancien modèle des dérouleurs de bandes cher au Pascal original de Wirth, encore que les propriétés telles que Position permettent de revenir en arrière.
Quoiqu'il en soit, les tableaux de caractères sont restés.

Historiquement, la classe avait 2 caractérstiques que Delphi 2 m'ont permis de supprimer:

  • le traitement se faisait par une mécanique de 'tampon double' qui permettait de traiter efficacement des textes ayant des tailles des plus de 64 K
  • la taille précise du tableau étant inconnue, un tableau ayant un indice 0..0 était utilisé, et l'ensemble des accès se faisait sous R-. Les tableaux indéfinis (ARRAY OF BYTE) ont résolu ce problume:
    • FileSize fournit la taille du fichier
    • SetLength dimensionne le tableau à l'octet près
    Et R+ permet à nouveau de détecter tout débordement d'indice.

2 - Utilisation

2.1 Interface

L'interface est la suivante:

    type c_text_fileclass(c_basic_file)
                        public
                          m_pt_buffert_oa_characters;
                          m_buffer_sizem_buffer_indexInteger;

                          m_has_removed_ctr_zboolean;
                          m_has_line_feedBoolean;

                          m_c_linec_line;
                          m_from_to_endm_from_to_beginInteger;

                          constructor create_text_file(p_namep_file_nameString); Virtual;

                          function f_loadBooleanvirtual;
                          function f_load_with_fat(p_factorInteger): Booleanvirtual;
                          procedure assign_buffer(p_ptPointerp_sizeInteger);
                          function f_read_lineBooleanvirtual;
                          function f_end_of_textbooleanvirtual;

                          procedure listvirtual;
                          procedure dump_hex(p_beginp_endInteger);

                          function f_saveBoolean;
                          procedure save_in_u_directory_with_extension(p_namep_extensionString);

                          function f_write(p_textString): Boolean;
                          function f_write_line(p_textString): Boolean;

                          function f_read_from_to(p_beginp_endInteger): String;
                          function f_write_from_to(p_textString): Boolean;

                          function f_extract_string_start_length(p_startp_lengthInteger): String;
                          function f_extract_string_start_end(p_startp_endInteger): String;
                          procedure skip_alternate_return_line_feed(var pv_indexInteger);
                          procedure skip_end_of_line(var pv_indexInteger);

                          function f_ascii_signatureInteger;

                          destructor DestroyOverride;
                      end;

Et:

  • m_pt_buffer: le tampon des caractères
  • m_buffer_size, m_buffer_index: taille du tampon et indice courant

  • m_has_line_feed: l'analyse a trouvé un caractère 10 dans le tampon

  • m_c_line: la classe ligne courante, si elle est utilisée
  • m_from_to_end, m_from_to_begin: indices utilisés pour les lectures partielles
Quant aux méthodes:
  • create_text_file: construit la classe

  • f_load: charge le tampon
  • f_load_with_fat: alloue un multiple de la taille du fichier et charge le tampon (pour les transformations qui produisent un texte plus important que l'original)
  • assign_buffer: affecte un autre tampon à la classe
  • f_read_line: lecture d'une ligne
  • f_end_of_text: détection de la fin du texte

  • list; virtual;
  • dump_hex(p_begin, p_end: Integer);

  • f_save: sauvegarde du tampon
  • save_in_u_directory_with_extension: sauvegarde du tampon dans un sous répertoire "u"

  • écriture par BlockWrite
    • f_write
    • f_write_line
  • lecture par BlockRead
    • f_read_from_to
    • f_write_from_to
  • analyse du texte:
    • f_extract_string_start_length
    • f_extract_string_start_end
    • skip_alternate_return_line_feed
    • skip_end_of_line
  • f_ascii_signature: calcul d'une signature simple

2.2 Un premier exemple simple

Voici un exemple qui liste simplement le contenu d'un fichier ASCII:

        with c_text_file.create_text_file('self'k_file_namedo
        begin
          list;
          Free;
        end// with c_text_file

2.3 Un mini analyseur syntaxique

Notre second exemple sera un analyseur syntaxique simplifié.
  • Nous isolons les symboles suivants:

            type t_token_type= (e_unknown,
                                e_identifiere_numbere_string_litterale_operator,
                                e_comment,
                                e_end_token);

  • La détection de chaque type de symbole se fait à partir du premier caractère:

                if m_buffer_indexm_buffer_size
                  then begin
                      case m_pt_buffer[m_buffer_indexof
                        'a'..'z''A'..'Z' : get_identifier;
                        '0'..'9' : get_number;
                        '(' : if (m_buffer_index+ 1< m_buffer_sizeand (m_pt_buffer[m_buffer_index+ 1]= '*')
                                then skip_comment_parenthesis
                                else get_operator;
                        '/' : if (m_buffer_index+ 1< m_buffer_sizeand (m_pt_buffer[m_buffer_index+ 1]= '/')
                                then skip_comment_slash
                                else get_operator;
                        '{' : skip_comment_curly_braket;
                        else get_operator;
                      end// case

    Notez nous devons traiter spécialement les cas où un seul caractère ne suffit pas ("//", "(*" dans notre cas, ":=" "<=" etc pour Pascal). En effet seul le premier caractères ne suffit pas dans ces cas ("/" peut être l'opérateur de division, ou le double slash du commentaire en début de ligne).

  • chaque cas appelle une procédure spécifique qui analyse la suite du symbole. Voici, à titre d'exemple le traitement pour les identificateurs:

              procedure get_identifier;
                var l_startl_lengthInteger;
                begin
                  l_token_type:= e_identifier;
                  l_start:= m_buffer_index;
                  while (m_buffer_indexm_buffer_sizeand (m_pt_buffer[m_buffer_indexin k_identifierdo
                    inc(m_buffer_index);
                  l_length:= m_buffer_indexl_start;
                  if l_length> 0
                    then begin
                        SetLength(l_token_stringl_length);
                        Move(m_pt_buffer[l_start], l_token_string[1], l_length);
                      end
                    else l_token_string:= '';
                end// get_identifier

    Notez que nous aurions pu utiliser ici f_extract_string_start_end

2.4 Voir aussi

Cette classe est souvent utilisée avec:
  • c_line qui permet une analyse ligne à ligne
  • u_handle_files_in_dirs qui balaye une arborescence DOS et peut effectuer des traitements sur tous les fichiers ASCII rencontrés

2.5 - Répertoires et Directives de compilation

L'unité est prévue pour être placée dans:

C:
  programs
    colibri_helpers
      units

Vous pouvez naturellement changer cette organisation par Projet | Options | Directories

Les directives de compilation sont:

  • R+ (vérification des intervalles)
  • S+ (vérification de la pile)
  • pas d'optimisation

3 - Programmation

Cette classe bénéficie tout d'abord de toutes les possibilités de sa classe ancêtre `c_basic_file: ouverture, création, changement de nom etc.

Elle offre en plus la gestion du tampon de caractères.


4 - Améliorations


5 - Télécharger

Vous pouvez télécharger: Avec les mentions d'usage:
  • j'apprécie tous les commentaires, remarques ou critiques
  • signalez-moi les bugs que vous trouverez.

L'auteur

John COLIBRI est passionné par le développement Delphi et les applications de Bases de Données. Il a écrit de nombreux livres et articles, et partage son temps entre le développement de projets (nouveaux projets, maintenance, audit, migration BDE, migration Xe_n, refactoring) pour ses clients, le conseil (composants, architecture, test) et la formation. Son site contient des articles avec code source, ainsi que le programme et le calendrier des stages de formation Delphi, base de données, programmation objet, Services Web, Tcp/Ip et UML qu'il anime personellement tous les mois, à Paris, en province ou sur site client.
Created: jan-04. Last updated: mar-2020 - 250 articles, 620 .ZIP sources, 3303 figures
Contact : John COLIBRI - Tel: 01.42.83.69.36 / 06.87.88.23.91 - email:jcolibri@jcolibri.com
Copyright © J.Colibri   http://www.jcolibri.com - 2001 - 2020
Retour:  Home  Articles  Formations  Développement Delphi  Livres  Pascalissime  Liens  Download
l'Institut Pascal

John COLIBRI

+ Home
  + articles_avec_sources
    + bases_de_donnees
    + web_internet_sockets
    + services_web_
    + prog_objet_composants
    + office_com_automation
    + colibri_utilities
    + uml_design_patterns
    + graphique
    + delphi
    + outils
    + firemonkey
    + vcl_rtl
    + colibri_helpers
      – u_types_constants
      – u_strings
      – u_loaded
      – u_c_basic_object
      – u_c_display
      – u_dir
      – u_file
      – u_display_hex
      – u_c_file_name
      – u_c_basic_file
      – u_c_log
      – u_c_line
      – handle_files
      – u_c_path_segments
      – u_c_text_file
      – u_c_direct_acccess
      – u_c_string_file
      – u_c_file_of
    + colibri_skelettons
    + admin
  + formations
  + developpement_delphi
  + présentations
  + pascalissime
  + livres
  + entre_nous
  – télécharger

contacts
plan_du_site
– chercher :

RSS feed  
Blog