Recherche dans un fichier texte. [Résolu]

vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - 14 juin 2016 à 08:15 - Dernière réponse : vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention
- 29 juin 2016 à 10:25
Bonjour,

j'explique mon problème.

J'ai un petit programme à faire pour récupérer une partie d'un fichier .txt à l'aide d'un intervalle d'octet (Ex: [56000;58000], va me donner le texte compris entre le 56000 et 58000 octet)
Un octet est "grossièrement" 1 caractère. (Hormis pour les retours à la ligne qui comptent pour 2 octets).
Mon intervalle d'octet est stocké en base de données. La récupération de ces données n'est pas un problème.
Je ne vois, à l'inverse, pas par quelle méthode, ou comment je pourrais faire pour rechercher dans mon fichier .txt avec les octets directement.
Je pourrais, je ne sais par quel procédé, compter les caractères dans mon fichier .txt ? et compter 2 fois si j'ai un retour à la ligne ?
sachant que les fichiers .txt sont très volumineux. (2MO < x < 4MO)

Je reste à votre disposition si je n'ai pas été clair.
Cordialement, et par avance, merci.
Afficher la suite 

Votre réponse

16 réponses

Meilleure réponse
vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - 29 juin 2016 à 10:25
1
Merci
A final, j'ai trouvé une alternative pour mes recherches.

Sachant que je ne peux pas me fier aux Octets dû à des incohérences dans la base de données. (Société extérieure donc indépendante de toute modification)

Je pose donc mon code dans le cas ou certaines personnes auraient le même type de recherche à effectuer.

Je prend une partie d'un fichier et je la copie dans un fichier créé.
On effectue ensuite notre lecture et on copie dans le fichier fraîchement créé.
A chaque "bilan apprentissage" on s’arrête, on recréé un nouveau fichier et ainsi de suite jusqu'à arriver en fin de fichier.

PROCEDURE traitement.CreationFichier(Date : String);
var
Recuperation : integer;
Filedelete : String;

BEGIN
FichierName := 0; // Creation du CR unique ( Provisiorement )

//Ouverture du fichier CR jour
AssignFile(myFile, 'C:\Users\Administrateur\Desktop\DatasBAF2A\CR' + date + '.txt');
Reset(myFile);
//Création du fichier CR unique
AssignFile(newFile, 'C:\Users\Administrateur\Desktop\test\Fichier_'+ date + '_' + inttostr(FichierName) + '.txt');
Rewrite(newFile);

//tant que nous ne sommes pas en fin de fichier
WHILE NOT Eof(myFile) DO
BEGIN
ReadLn(myFile, Stg);
//Découpage repéré par la ligne de bilan apprentissage
IF (Stg = '/11************************* BILAN APPRENTISSAGE 1***************** ' ) THEN
BEGIN
FichierName := FichierName + 1;
CloseFile(newFile);
AssignFile(newFile, 'C:\Users\Administrateur\Desktop\test\Fichier_'+ date + '_' + inttostr(FichierName) + '.txt');
Rewrite(newFile);
END;
WriteLN(newFile, Stg);
END;

CloseFile(myFile);
CloseFile(newFile);

END;

Merci vico8000 1

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de vico8000
nagaD.scar 4269 Messages postés samedi 8 septembre 2007Date d'inscription 29 août 2018 Dernière intervention - Modifié par nagaD.scar le 14/06/2016 à 17:01
0
Merci
Salut,

Je souhaiterai juste dans un premier temps parler des tailles:

- 1 octet représente un caractère, pas "grossièrement" mais tout cours.
- une fin de ligne peu être sur un ou deux octets en fonction de l encodage => soit c'est "\r\n" donc 2 caractères , soit "\r" soit "\n" donc 1 caractère (rappel: 1 caractère est sur 1 octet).

Une chose a savoir aussi, un fichier peu contenir un en-tête (par exemple un encodage utf8 bom ajoutera 2 caractères) => en gros il faut que tu connaisse l encodage pour déterminer la valeur a soustraire au final.

Ensuite, sachant qu'un caractère=un octet, il te suffit de récupérer la taille du fichier (a prioris c'est la fonction FileSize de system - elle renvoi la taille en octets ... parfais !).
si le fichier a une entete, soustrait la taille.

Aussi, tu peux retirer 1 caractère pour le "end of file".

Maintenant tu connais le nombre de caractères, incluant les saut de ligne.

Pour savoir quel est (quels sont) le(s) caractère(s) de fin de ligne, lis caractère par caractère et fais un check (dès que tu termine la première ligne, stop)


Par contre pour connaitre le nombre de lignes, il va falloir que je sache si la taille d une ligne est fixe (là c'est simple) ou non ... et si non, pas le choix il va falloir que tu lises une fois tout le fichier pour savoir.

Je suis pas sûre d'être complètement dans le sujet, je pense qu'il manque des choses que je n'ai pas bien compris mais en lisant ca tu pourra au moins avoir des point pour rendre ta demande plus claire ^^

naga
Commenter la réponse de nagaD.scar
vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - Modifié par vico8000 le 15/06/2016 à 09:02
0
Merci
Bonjour,

Le saut de ligne est codé sur 2 Octets. (Linux/Unix pour les sauts de ligne sur 1 octet ?)

Je suis en encodage Utf-8. Malgré tout, les deux octets d'en-tête et l'octet de fin de fichier sont-ils à prendre en compte ? (Je ne pense pas, j'aurais des incohérences dans mes données après)

Merci pour la fonction FileSize, je me pencherais dessus un peu plus tard. (Je stocke de l'information sur comment procéder avant de commencer le développement)


"Par contre pour connaitre le nombre de lignes, il va falloir que je sache si la taille d une ligne est fixe (là c'est simple) ou non ... et si non, pas le choix il va falloir que tu lises une fois tout le fichier pour savoir."

Je vais donc être obligé de lire ligne par ligne, ma taille de ligne n'est absolument pas fixe. Le fait d'avoir des fichier avec 3M de caractères ne va pas provoquer des problèmes de latence ?


Dans l'idée (si je n'ai pas été clair), je souhaiterai développer une application pour mon entreprise, afin de faire une recherche d'erreurs dans un fichier texte.
Une machine nous sort un rapport journalier dans un fichier texte et remonte certaines données dans une BDD.
Actuellement, nous ne faisons pas le lien entre les deux.
Dans la base de données, nous avons en "gros" une date, et un nombre d'octets. (beaucoup plus compliqué que ça dans la réalité mais le reste des champs ne rentrent pas en compte pour ce projet)
Le nombre d'octets stockés dans la base de données se présentent sous cette forme:
- Le premier enregistrement prend 700 Octets, champ Octet=700
- Le deuxième enregistrement prend 500 Octets, champ Octet=1200
- ...

Dans ce rapport journalier, est édité toutes les erreurs qui sont survenues.
Le but serait donc, depuis l'application, de choisir une date dans un listbox. Cette dernière va chercher le champ octet correspondant. Nous avons notre fin d'enregistrement désiré.
Nous regardons l'enregistrement précédent de celui que nous venons d'avoir pour récupérer à nouveau le champ octet. Celui-ci nous donnera notre début de lecture.
Enfin, afficher ce que nous avons été rechercher.

J’espère avoir été le plus clair possible.
Sinon, je reste toujours à disposition.

Cordialement.
Commenter la réponse de vico8000
Whismeril 12122 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 21 octobre 2018 Dernière intervention - 15 juin 2016 à 09:11
0
Merci
Bonjour, si ton but est de récupérer toutes les occurrences d'un pattern : 2 entiers entre crochets séparés pas ; alors tu peux regarder du côté des regex.
vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - 15 juin 2016 à 09:24
Régular Expression, ce n'est pas pour rechercher dans le texte par un mot clé ?
Je n'ai jamais eu l'occasion d'utilisé ce type de fonction.

Cordialement.
Whismeril 12122 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 21 octobre 2018 Dernière intervention - 15 juin 2016 à 14:21
Non justement c'est pour mettre un pattern
Commenter la réponse de Whismeril
nagaD.scar 4269 Messages postés samedi 8 septembre 2007Date d'inscription 29 août 2018 Dernière intervention - 15 juin 2016 à 10:20
0
Merci
Je commente les deux réponses:
- "Le saut de ligne est codé sur 2 Octets. (Linux/Unix pour les sauts de ligne sur 1 octet ?) ". Il me semble que c'est le cas par défaut, mais ca ne sous entends pas que tu ne trouvera l'inverse (au final c'est l encodage qui importe).

- Concernant la lecture du fichier, si l idée est de faire un passage préalable (en background, juste pour connaitre les positions), ca ne provoquera pas de latence vu que pas d'utilisateur. Ensuite si a chaque demande tu fais la lecure oui ca risque de provoquer une latence, mais pour un fichier de petite taille, c'est négligeable (a la louche, le parcours complet prendra entre 0.5 et 4 secondes) ... bien sûr ca dépendra des tests (si tu fais 50 test pour chaques caractères, ca sera plus long).

- Concernant les regex, grossomodo oui c'est une recherche par mot clef dans du texte mais "conditionable" (je veux pas expliquer, trop long, mais fais un tour sur le net et tu comprendra vite).

Pour ce qui est de ton projet,


Une machine nous sort un rapport journalier dans un fichier texte et remonte certaines données dans une BDD.
Actuellement, nous ne faisons pas le lien entre les deux.
Dans la base de données, nous avons en "gros" une date, et un nombre d'octets. (beaucoup plus compliqué que ça dans la réalité mais le reste des champs ne rentrent pas en compte pour ce projet)


Si je comprends bien, tu possèdes déjà toutes les infos non?

Là je t avoues que je suis perdu .. tu possède le fichier et tu peux accéder au descriptif. Quand tu dis qu'il n y pas de lien, que sous entends tu?
vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - 15 juin 2016 à 12:17
En effet, je pense que je partais dans la mauvaise direction.
Après réflexion, le fichier et la base de données ne se croisent pas. ( Alors que cela devrait, problème avec les appli externes ou tu n'as pas la main dessus ) Le nombre d'octet stocké en base de données est incohérent. je ne peux donc pas faire le lien avec mon fichier. De plus, un fichier à part est crée avec les erreurs (matérialisées par un code /xxxxxxx). il faut que je fasse donc le lien avec ce fichier au lieu du précédent. Dans ma base de données, il est indiqué quand j'ai une erreur. Il me suffit juste de compter le nombre d'erreurs avant la date sélectionnée pour retrouver le bon code. Le principe à l'air beaucoup plus simple dans ce sens la. Il n'y a aucune conversion à effectuer, ...
De plus, si j'ai besoin à un moment quelconque de compter les octets, je pourrais le faire plus aisément puisque toutes les lignes sont de la même dimension et les différents temps sont séparés par un saut de ligne.
Du coup je fais une boucle qui test toute la base de données pour erreur!=0 et quand erreur différent de 0 je passe dans un listbox l'heure et la date.
nagaD.scar 4269 Messages postés samedi 8 septembre 2007Date d'inscription 29 août 2018 Dernière intervention - 15 juin 2016 à 12:25
Ok!

Du coup tu as trouvé ta solution à prioris ^^ n'hésites pas a redemander si tu coinces !
naga
vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - 15 juin 2016 à 13:20
Je ne clot pas le sujet, comme ça, si besoin, je poserais directement ici.
Je te ferais signe de mon avancé dans le cas ou je n'aurais pas besoin d'aide.
Encore merci.
Cordialement.
nagaD.scar 4269 Messages postés samedi 8 septembre 2007Date d'inscription 29 août 2018 Dernière intervention - 15 juin 2016 à 13:57
ca marche :) bon dev!
vico8000 291 Messages postés lundi 18 janvier 2016Date d'inscription 14 février 2018 Dernière intervention - 15 juin 2016 à 13:59
Merci. Bonne continuation.
Commenter la réponse de nagaD.scar
0
Merci
Salut,
Pour "rechercher / utiliser" un fichier texte il existe plusieurs solutions, TFileStream, TMemoryStream, TStringStream, File, TextFile, TStringList,... tout dépend de la structure du fichier. Si tu connais la position dans le fichier texte alors TFileStream, TMemoryStream... permet de se positionner où l'on souhaite, avec par exemple Position, Seek et ensuite lire la longueur que l'on veut en incluant les "caractères" de fin de ligne, tabulation etc... et même gérer les encodages avec TEncoding.
Si dans le fichier texte la structure est bien défini avec des trames style fichier csv, "", ; : / ou fixe comme un record TStringList et TextFile peuvent très bien faire le taf...
La réponse et la solution à ta question est très variable de la structure du fichier texte et de la façon de se déplacer et de l'utiliser...Peut-être vas tu trouver la solution dans les termes que je t'ai donné.
@+
Commenter la réponse de Yanb

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.