VB - Ordnerstruktur im Datumsformat auswerten



  • Hallo,
    ich versuche eine Ordnerstruktur in der Form 2016/7/20/18/20/45/daten.txt auszuwerten.
    Also jeder Teil eines Datums+Uhrzeit stellt einen Ordner dar und im Ordner mit den Sekunden liegt dann die Textdatei mit den Daten.
    Alle 30 Sekunden wird ein Datensatz in so eine Struktur gespeichert.
    Nun versuche ich beispielsweise alle Datensätze der letzten Woche oder eines beliebigen Zeitabstandes zu lesen.
    Wie gehe ich vor, um genau die Datensätze einzulesen, die in diesem Zeitintervall liegen?



  • Du könntest eine Schleife über deinen Zeitraum mit Schritt 30 Sekunden machen und dann jeweils prüfen, ob es dafür einen Ordner in deiner genannten Struktur gibt. Wenn ja, wertest du die Daten aus:

    private List<string> getDirectoriesForTimeSpan(DateTime dateTimeFrom, DateTime dateTimeTo)
    {
    	List<string> directories = new List<string>();
    
    	for (; dateTimeFrom <= dateTimeTo; dateTimeFrom = dateTimeFrom.Add(new TimeSpan(0, 0, 30)))
    	{
    		string year = dateTimeFrom.Year.ToString();
    		string month = dateTimeFrom.Month.ToString();
    		string day = dateTimeFrom.Day.ToString();
    		string hour = dateTimeFrom.Hour.ToString();
    		string minute = dateTimeFrom.Minute.ToString();
    		string second = dateTimeFrom.Second.ToString();
    
    		string dataDirectory = "";
    
    		if (!doesDirectoryExist(year, ref dataDirectory)) continue;
    		if (!doesDirectoryExist(month, ref dataDirectory)) continue;
    		if (!doesDirectoryExist(day, ref dataDirectory)) continue;
    		if (!doesDirectoryExist(hour, ref dataDirectory)) continue;
    		if (!doesDirectoryExist(minute, ref dataDirectory)) continue;
    		if (!doesDirectoryExist(second, ref dataDirectory)) continue;
    
    		// Treffer!
    		directories.Add(dataDirectory);
    	}
    
    	return directories;
    }
    
    private bool doesDirectoryExist(string directory, ref string fullPath)
    {
    	if (fullPath.Length > 0)
    	{
    		fullPath += "\\";
    	}
    
    	fullPath += directory;
    
    	return Directory.Exists(fullPath);
    }
    

    Du kannst dann getDirectoriesForTimeSpan mit zwei DateTime-Werten aufrufen, um alle Pfade zu ermitteln, die in diesem Zeitraum existieren. Zum Beispiel für Zeitraum 21.07.2016 00:00:00 bis 22.07.2016 00:00:00 so:

    List<string> directories = getDirectoriesForTimeSpan(new DateTime(2016, 7, 21, 0, 0, 0), new DateTime(2016, 7, 22, 0, 0, 0));
    


  • Danke für die Antwort.
    Sorry, hab mich bisschen unklar ausgedrückt.
    Es sind nur ca. 30s, also das Intervall schwankt ein bisschen.

    Bis jetzt habe ich eine rekursive Funktion, die alle Ordner durchläuft und ein Startdatum als Parameter, ab dem alle Ordner, deren Datum höher ist, ausgelesen werden sollen.
    Das Problem ist jetzt, dass ich aus dem Strings z.B. im Ordner "2016", dann "7" usw. schrittweise ein Date-Objekt, dass dieses Datum enthält aufbauen muss, um dann mittel DateDiff(startdatum, aktdatum) festzustellen ob der aktuelle Ordner älter ist als das Startdatum und somit ausgewertet werden muss.
    (Kann es eventuell mit der Rekursion ein Problem geben, wenn z.B. die Datensätze eines ganzen Jahres ausgewertet werden, was ja dann extrem viele sind).



  • Hi!

    Ich dachte auch erst daran, die Ordner durchzuloopen und dann jeweils ein Datumsobjekt daraus zu füllen, das dann mit einem Zeitraum verglichen wird. Ich dachte nur, dass es performanter wäre, über Datumsobjekte zu loopen. Aber da du sagst, dass das Intervall leicht abweicht, wirst du wohl tatsächlich nicht drum rum kommen, über die Ordner zu loopen, da du ansonsten einen sekündlichen Schritt machen müsstest und dann wird es langsam.

    Deine Rekursion sollte ja maximal 6 Ebenen beinhalten: Jahr, Monat, Tag, Stunde, Minute, Sekunde. Spätestens da ist ja Schluss mir Rekursionstiefe, weil es unter der Sekunde bei dir nichts mehr gibt, oder hab ich was falsch verstanden?

    Poste doch deinen Code mal hier, dann können wir die wahrscheinlich gezielter helfen!



  • Hmm..

    nehm doch den anfangs- und end zeitstempel.

    pseudo;

    DateTime from = ....
    DateTime to = from.AddMinutes(100);
    
    for(int i=0; i< to.TotalMinutes ; ++i)
    {
      DateTime dir = from.AddSeconds(1);
    
      string path =  dir.Year +"\\" + dir.Month+ "\\".......;
    }
    

    oder hab ich da jetzt zu einfach gedacht?;)



  • Wenn du dann aber beispielsweise einen Filterzeitraum von einem Jahr hast, hast du schon mal 365 * 24 * 60 * 60 = 31536000 Schleifendurchläufe, auch wenn es vielleicht nur 50 Ordner gibt. Dann pro Durchlauf ein API-Aufruf zum Prüfen, ob der jeweilige Ordner existiert.

    Da wäre es wohl geschickter, über die vorhandenen Ordner zu loopen und dann zu prüfen, ob der Zeitpunkt, der sich aus dem jeweiligen Ordnernamen ergibt, in den Filterzeitraum passt.



  • Der bisherige Code sieht so aus.
    actdate ist das Datum, ab dem alle Ordner ausgewertet werden.
    Allerdings funktioniert der Aufbau der Datumsobjekte mit dem DateAdd() nicht korrekt, da kommen falsche Datumsobjekte raus, gibt es da ne bessere Möglichkeit aus Jahr, Monat, ... ein Datumsobjekt Stück für Stück aufzubauen?

    Public Sub parseData(ByVal folder As String, ByVal folder_date As Date, ByVal actdate As Date, ByVal intervaltype As DateInterval, ByRef werte As Messwerte)
            Dim data_folder As Boolean = True
            Dim n_folder_date As Date
            Dim ds As Datensatz = New Datensatz
            For Each subfolder In My.Computer.FileSystem.GetDirectories(folder)
                Dim subfolder_time As Integer
                Dim sp As String() = subfolder.Split("\")
                n_folder_date = DateAdd(DateInterval.Second, 0, folder_date)
                subfolder_time = Val(sp(sp.Length - 1))
                data_folder = False
                Dim n_intervaltype As DateInterval = intervaltype
                If intervaltype = DateInterval.Year Then
                    n_intervaltype = DateInterval.Month
                ElseIf intervaltype = DateInterval.Month Then
                    n_intervaltype = DateInterval.Day
                ElseIf intervaltype = DateInterval.Day Then
                    n_intervaltype = DateInterval.Hour
                ElseIf intervaltype = DateInterval.Hour Then
                    n_intervaltype = DateInterval.Minute
                ElseIf intervaltype = DateInterval.Minute Then
                    n_intervaltype = DateInterval.Second
                End If
    
                If intervaltype = DateInterval.Year Or intervaltype = DateInterval.Month Or intervaltype = DateInterval.Day Then
                    n_folder_date = DateAdd(intervaltype, subfolder_time - 1, n_folder_date)
                Else
                    n_folder_date = DateAdd(intervaltype, subfolder_time, n_folder_date)
                End If
    
                Debug.WriteLine("Subfolder: " & subfolder)
                Debug.WriteLine("Subfolder date: " & n_folder_date.ToString())
                mainfrm.log("subfolder:" & subfolder)
    
                If sp.Length > 1 Then
                    Dim dif As Long
                    dif = DateDiff(intervaltype, n_folder_date, actdate)
                    If dif <= 0 Then
                        mainfrm.log("parsing subfolder ..")
                        parseData(subfolder, n_folder_date, actdate, n_intervaltype, werte)
                    End If
                End If
            Next
    
            Try
                ds.parseValues(folder & "/messung.txt")
                werte.X.Add(ds.douX)
                werte.Y.Add(ds.douY)
                werte.Z.Add(ds.douZ)
                werte.t.Add(ds.douT)
                werte.V.Add(ds.douV)
                werte.d.Add(ds.iD)
            Catch ex As Exception
    
            End Try
    
    End Sub
    


  • Voschlag zum Nachdenken:
    Du benennst die Ordner im Format NameJJJJMMTTHHMMSS, also z.B. "XXX20160828113830".
    Du hast danmit ein Sortierkriterium in der Benennung, was das spätere Filtern stark vereinfacht.


Anmelden zum Antworten