StreamReader lit bien tout mais nombre d'octets incohérent [Résolu]

Messages postés
14010
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
- - Dernière réponse : cs_Jack
Messages postés
14010
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
- 6 avril 2013 à 02:13
Salut ta tou(te)s

Je lis un fichier texte avec un StreamReader (avec encodage UTF-8 adéquat).
Je ne lis que des fragments de 1ko à la fois (gros fichiers) que je stocke dans un buffer avec lequel je travaille ensuite.
Le ReadBlock remplit bien mot tableau de Char.
Le retour de l'instruction me renvoie bien le nombre de Chars lu (= à la taille de mon tableau)
Pour mon essai, le fichier ne fait que 6742 octets (.BaseStream.Length confirmé par l'explorateur de fichiers).
J'ai cumulé 6731 chars de lecture et ... le EndOfStream est déjà à True et je n'ai pas compté 11 chars alors que je les ai bien tous lus.

Pourquoi le cumul du nombre de Chars lus ne tombe t-elle pas sur la taille totale du fichier ?
Est-ce mon approximation 1 Char = 1 Octet est vraie ?

    Private Function GetDataFromFile(Optional ByRef CharToRead As Integer = cstDefaultBufferLength) As Boolean
        ' Ici, on ne fait que lire les données + decodage --> Buffer
        Dim lLength As Integer
        If FhxReader Is Nothing OrElse Not (FhxReader.BaseStream.CanRead) Then Return True
        If lBufferPointer + CharToRead > FhxReader.BaseStream.Length Then
            lLength = CInt(FhxReader.BaseStream.Length - lBufferPointer)
        Else
            lLength = CharToRead
        End If
        If (Not FhxReader.EndOfStream) And (lLength > 0) Then
            Dim aLocalBuffer(0 To (lLength - 1)) As Char
            Dim lBytesRead As Integer = _
                   FhxReader.ReadBlock(aLocalBuffer, 0, aLocalBuffer.Length)
            If lBytesRead > 0 Then
                lBufferPointer = lBufferPointer + lBytesRead
                ReDim Preserve aLocalBuffer(lBytesRead - 1)
                sFhxBuffer = sFhxBuffer & New String(aLocalBuffer)
            End If
        Else
            ' Plus rien à lire
            If FhxReader.EndOfStream And (lLength > 0) Then
                Console.WriteLine(lBufferPointer.ToString)
                Debug.Assert(False)
            End If
        End If
        ' True si fin de fichier
        Return FhxReader.EndOfStream

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on le partage (Socrate)
Afficher la suite 

Votre réponse

5 réponses

Meilleure réponse
Messages postés
14423
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 avril 2019
155
3
Merci
Bonjour,

Une fois la lecture faite, tu peux convertir les données en tableau d'octet (System.Text.Encoding.*) et te servir du nombre de case du tableau pour calculer ta progression.

v----Signature--------v----------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 112 internautes nous ont dit merci ce mois-ci

Commenter la réponse de NHenry
0
Merci
Bonjour,

Hé bien, j'ai lu ça:
un octet egal 8 bit donc peut être un caractère (en ascii étendu)
car il faut 9bits en ebcdic ,7 bits en ascii,5 bit en baudot.....


Sur CE FORUM

Es-tu sur du format d'encodage?

Cordialement


CF2i - Guadeloupe
Ingénierie Informatique
Commenter la réponse de Utilisateur anonyme
Messages postés
14423
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 avril 2019
155
0
Merci
Bonjour,

Sinon, en UTF-8, les caractères au-dessus de 127 sont codés sur plus de 1 octet, d'où une différence entre le nombre d'octet et de caractères.

v----Signature--------v----------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
Commenter la réponse de NHenry
Messages postés
14010
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
77
0
Merci
Oui, je m'en doutais à moitié.
Mais dans ce cas, comment faire pour suivre l'avancement de lecture d'un fichier qu'on ne peut raisonnablement pas charger en entier en mémoire ?
Y a t-il un moyen de compter le nombre de bytes/octets contenus dans un tableau de Char ou un String ?
Commenter la réponse de cs_Jack
Messages postés
14010
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
77
0
Merci
Oui voilà, toujours cette histoire d'encodage.
Pour le résoudre, j'ai donc continué à lire les Chars, mais je calcule à part le nombre de Bytes avec la méthode suivante (au milieu de mon code) :
If lBytesRead > 0 Then
    ' Ajuste la taille du tableau en fonction du nombre de char réellement lus
    ReDim Preserve aLocalBuffer(lBytesRead - 1)
    ' Mise à jour du buffer principal
    sFhxBuffer = sFhxBuffer & New String(aLocalBuffer)
    ' Prépare une retranscription sous forme de Bytes (UTF-8 imposé par mon fichier)
    Dim oEncoder As Encoding = New UTF8Encoding(True, True)
    Dim aLocalBytes() As Byte = oEncoder.GetBytes(aLocalBuffer)
    ' Et voilà la vraie longueur en Bytes de mes données
    Dim lByteLength As Integer = aLocalBytes.Length
    ' Mise à jour du pointeur
    lBufferPointer = lBufferPointer + lByteLength
End If
Et là, c'est cohérent.

Merci Nicolas, tu as confirmé mes soupçons.
Commenter la réponse de cs_Jack

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.