Réduction de la durée de conversion et lecture
Bonjour à tous,
La présentation
J'ai une application VB6 (c'est bien le .net qui m’intéresse) qui me récupère et stock des données en CSV sous la forme:
Test1;0
Battery Current;Adc
20/07/2010 08:50:38;26/07/2010 02:20:38
20/07/2010 08:50:38;-50.2
20/07/2010 09:00:38;-50.2
20/07/2010 09:10:38;-50.2
20/07/2010 09:20:38;8.7
20/07/2010 09:30:38;8.4
20/07/2010 09:40:38;4.9
20/07/2010 09:50:38;4.6
20/07/2010 10:00:38;4.2
20/07/2010 10:10:38;-38.00
20/07/2010 10:20:38;-70.9
20/07/2010 10:30:38;-70.1
etc...
Le 1er champs et donc l'heure d'acquisition de la donnée, le 2eme étant la donnée. Les 3 première ligne d’entête permet de connaitre:
1ere ligne: Le nom du site, ici "Test1" suivit de la version du fichier (il peut y avoir plusieurs "Test1").
2eme ligne étant le nom de la mesures suivi de l'unité.
3eme ligne étant la date de début suivi de la date de fin, ce qui me permet quand j'affiche tout les fichiers disponibles, de parcourir que ces 3 lignes pour m'indiquer ce que les fichiers contiennent.
Voila pour la mise en place du programme VB6
Pour la lecture de ce fichier j'utilise un programme qui va m'afficher la courbe grâce à la dll ZedGraph, Voici ce que donne la courbe de Test1:
http://i49.servimg.com/u/f49/13/09/48/00/graph_11.jpg
Le fichier a un poids de 22Ko et 829 lignes
Voila pour la présentation.
Mon souci
Le client (dans le monde entier) peut m'envoyer un fichier à ouvrir en France. comme vous pouvez le constater, les données sont avec des points. Et mon souci c'est que en France si j'utilise la fonction Val ( "54.5") cela me crée une exception car il n'arrive pas a convertir avec le point. Mais avec un PC US pas de souci.
Ainsi pour que cela soit compatible partout j'ai crée une petit rustine:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
Public Function ConversionRegional(ByVal str As String) As Double
Dim val As Double
Try
If Not _DebLecture Then
If str.Contains(".") Then
_Point = True
Else
_Point = False
End If
_DebLecture = True
End If
If Not _Conversion Then
val = Convert.ToDouble(str)
Else
If _Point Then
str = Replace(str, ".", ",")
Else
str = Replace(str, ",", ".")
End If
val = Convert.ToDouble(str)
End If
ConversionRegional = val
Catch ex As Exception
If _Point Then
str = Replace(str, ".", ",")
Else
str = Replace(str, ",", ".")
End If
val = Convert.ToDouble(str)
_Conversion = True
ConversionRegional = val
End Try
End Function |
Le principe: J'envoie mon string à convertir, je crée une 1er tentative de conversion et si j'ai une exception je regarde si j'ai un point ou une virgule (par s'adapter à n'importe quelle fichier) puis je remplace et je reconverti pour enfin récupérer mon Double.
Pour la 2eme conversion si il y a eue une exception avant je remplace tout de suite le point ou la virgule. Etc...
Cela marche très bien mais c'est très long.
Par exemple pour convertir mon fichier de 22K il met presque 10 secondes (mon PC est certes pas rapide du tout comparer a celui de mon chef)
Pour envoyer ensuite les données à zedgraph c'est quasiment instantané, donc c'est vraiment cette conversion qui me bloque.
Voici le code qui me lit le fichier et me stocke les données dans un dico:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
Public Function LireFichier(ByVal _NomFichier As String, ByVal _DateMini As Date, _
ByVal _DateMaxi As Date, ByVal COurbe As frmCourbe) As Dictionary(Of Date, Double)
Dim Lecture As StreamReader = New StreamReader(_ChDonnee & "\" & _NomFichier)
Dim EcritureEr As StreamWriter
Dim Ligne As String
Dim Tab(2) As String
Dim Dico As New Dictionary(Of Date, Double)
Dim Defaut As ArrayList = New ArrayList
Dim Err As Integer
Dim Time As Date
Dim OK As Boolean = False
Dim Val As Single
Dim TextErr As String = ""
Err = 0
Try
Tab = Lecture.ReadLine().Split(";")
Tab = Lecture.ReadLine().Split(";")
Ligne = Lecture.ReadLine()
Ligne = Lecture.ReadLine()
While Not Ligne Is Nothing
Tab = Ligne.Split(";")
Time = Convert.ToDateTime(Tab(0))
Val = ConversionRegional(Tab(1))
If (_DateMini <= Time) And (Time <= _DateMaxi) Then
While Not OK
If Not Dico.Keys.Contains(Time) Then
Dico.Add(Tab(0), Val)
OK = True
Else
Err = Err + 1
Defaut.Add(_MaLangue.LoadPrgString("Message2") & vbCrLf & _
_MaLangue.LoadPrgString("Message4") & Tab(0) & vbCrLf & _
_MaLangue.LoadPrgString("Message3") & vbCrLf & _
"---------------------------------------------")
'Ajout d'une seconde à la valeur identique
Time = DateAdd(DateInterval.Second, 1, Time)
Tab(0) = Time
End If
End While
OK = False
End If
Ligne = Lecture.ReadLine
_Courbe.rafraichir()
End While
If Err <> 0 Then
EcritureEr = New StreamWriter(_ChDonnee & "\" & _NomFichier & "_Err.txt")
For i As Integer = 0 To Defaut.Count - 1
EcritureEr.WriteLine(Defaut(i))
Next i
EcritureEr.Close()
MessageBox.Show(Err.ToString & " " & _MaLangue.LoadPrgString("Message5") & vbCrLf & _NomFichier & "_Err.txt")
End If
Catch ex As Exception
MessageBox.Show("Error : 604 " & vbCrLf & _MaLangue.LoadPrgString("Message6") & vbCrLf & _MaLangue.LoadPrgString("Message4") & Tab(0) & vbCrLf & ex.ToString)
End Try
Return Dico
End Function |
Voila c'est un peut long mais je pense que vous avez tout pour essayer si vous le voulez bien, me dire comment réduire ce temps de lecture. Sachant qu'a Zegraph je lui donne la date du point et la données "Double" dans une boucle après cette conversion mais c'est presque instantané.
Merci