CCC-Fahrplan
Pünktlich zum aktuellen Chaos Communication Congress des CCC möchte ich ein kleines Projekt vorstellen.
Meine Variante des CCC-Fahrplans greift auf die XML- und JSON-Dateien des offiziellen Zeitplans zurück, stellt dadurch alle Veranstaltungen (seit 2006) und Sprecher (seit 2013) einheitlich dar und enthält einige Querverweise. Darüber hinaus ermöglichen die Flaggen eine besonders schnelle Sprachzuordnung direkt auf der Startseite.
Zur Schonung der Infrastruktur des CCC werden die Daten zwischengespeichert, sodass die angezeigten Informationen u. U. veraltet sein können. Bitte informiere dich für verbindliche Informationen direkt beim CCC.
Meine Variante des CCC-Fahrplans greift auf die XML- und JSON-Dateien des offiziellen Zeitplans zurück, stellt dadurch alle Veranstaltungen (seit 2006) und Sprecher (seit 2013) einheitlich dar und enthält einige Querverweise. Darüber hinaus ermöglichen die Flaggen eine besonders schnelle Sprachzuordnung direkt auf der Startseite.
Zur Schonung der Infrastruktur des CCC werden die Daten zwischengespeichert, sodass die angezeigten Informationen u. U. veraltet sein können. Bitte informiere dich für verbindliche Informationen direkt beim CCC.
Parameter einer Java-Methode per Reflexion ermitteln
Für ein kleines Projekt (mehr dazu in einem separaten Beitrag) war es notwendig, die Parameter von Methoden per Reflexion in Java zu ermitteln. Die entsprechende Funktionalität findet sich im Paket
Wir bereits früher angekündigt werde ich zur Reflexion in C# noch einen etwas ausführlicheren Beitrag schreiben und dann dort eine entsprechende Implementierung ähnlicher Funktionalität vorstellen.
java.lang.reflect
.
Parameter einer Java-Methode per Reflexion ermitteln
Ähnlich zu LINQ bei C# gibt es für Java sogenannte Streams; wir können obige Implementierung damit beispielsweise wie folgt unter einem funktionalem Paradigma schreiben:
0102030405060708091011121314151617181920
public static List<Map<String,String>> GetMethodParameterList( String typeName, String methodName) throws ClassNotFoundException { List<Map<String,String>> methodList = new ArrayList<>();
for(Method method : Class.forName(typeName).getMethods()) { if(method.getName().equals(methodName)) { HashMap<String,String> parameterList = new HashMap<>();
for(Parameter parameter : method.getParameters()) { parameterList.put(parameter.getName(), parameter.getType().getCanonicalName()); }
methodList.add(parameterList); } }
return methodList;}
Implementierung mit Java-Streams
Die Verwendung gestaltet sich jeweils identisch:
010203040506070809101112
public static List<Map<String,String>> GetMethodParameterList( String typeName, String methodName) throws ClassNotFoundException { return Stream.of(Class.forName(typeName).getMethods()) .filter(m -> m.getName().equals(methodName)) .map(m -> Stream.of(m.getParameters()).collect(Collectors.toMap( k -> k.getName(), v -> v.getType().getCanonicalName() ))) .collect(Collectors.toList());}
Methode verwenden und Ergebnis auf der Standardausgabe ausgeben
Es gilt schließlich noch eine kleine Besonderheit zu berücksichtigen: Standardmäßig stehen die Bezeichner der Parameter unter Java nicht zur Verfügung, sondern würden schlicht durchnummeriert. Um die tatsächlichen Bezeichner zu erhalten, muss mit der Option 01020304050607
List<Map<String,String>> methodList = GetMethodParameterList(typeName, methodName);
for(Map<String,String> parameterList : methodList) { for(Map.Entry<String,String> parameter : parameterList.entrySet()) { System.out.println(parameter.getValue() + " " + parameter.getKey()); }}
-parameters
kompiliert werden. Verbreitete Entwicklungsumgebungen wie Eclipse oder NetBeans bieten hierfür entsprechende Einstellungen.Wir bereits früher angekündigt werde ich zur Reflexion in C# noch einen etwas ausführlicheren Beitrag schreiben und dann dort eine entsprechende Implementierung ähnlicher Funktionalität vorstellen.
Wissen(schaft)spodcasts
In früheren Beiträgen hatte ich bereits ein paar Podcast-Empfehlungen ausgesprochen und auf mein Feedreader-Projekt hingewiesen, welches ebenfalls einige Podcasts aus verschiedenen Themenbereichen bereithält.
Mit diesem Beitrag möchte ich darüber hinaus gerne auf Wissenschaftspodcasts hinweisen. Diese Seite wurde von einigen Podcastern aus dem Bereich der Wissenschafts- und Wissensvermittlung ins Leben gerufen. Zu den Gründern gehören u. a. auch Nicolas Wöhrl von methodisch inkorrekt und Markus Völter von omega tau – beides Podcasts, die ich schon seit sehr langer Zeit verfolge und auch hier bereits beworben habe.
Die von den genannten und weiteren Personen eröffnete Seite bietet nun eine Sammlung verschiedenster Podcasts aus den Bereichen Wissen und Wissenschaft. Das Themenspektrum ist breit abgedeckt und reicht von Archäologie, Geschichte und Technik über Astronomie, Forschung im Allgemeinen und Speziellen bis hin zu Mathematik und Naturwissenschaften. Ich gehe also davon aus, dass für (fast) alle meiner – sicherlich hauptsächlich technisch interessierten – Besucher etwas dabei sein dürfte. Ihr könnt darüber hinaus auch neue Vorschläge einreichen.
Da mir die Vermittlung von Wissen und das Gespräch über wissenschaftliche Erkenntnisse persönlich äußerst wichtige Angelegenheiten sind, würde ich mich sehr freuen, wenn ihr etwas Passendes findet und die Seite(n) weiterempfehlt. Der Vollständigkeit wegen möchte ich abschließend noch kurz darauf hinweisen, dass ich mit den genannten Seiten in keiner weiteren Verbindung außer als Zuhörer einiger Podcasts stehe.
Mit diesem Beitrag möchte ich darüber hinaus gerne auf Wissenschaftspodcasts hinweisen. Diese Seite wurde von einigen Podcastern aus dem Bereich der Wissenschafts- und Wissensvermittlung ins Leben gerufen. Zu den Gründern gehören u. a. auch Nicolas Wöhrl von methodisch inkorrekt und Markus Völter von omega tau – beides Podcasts, die ich schon seit sehr langer Zeit verfolge und auch hier bereits beworben habe.
Die von den genannten und weiteren Personen eröffnete Seite bietet nun eine Sammlung verschiedenster Podcasts aus den Bereichen Wissen und Wissenschaft. Das Themenspektrum ist breit abgedeckt und reicht von Archäologie, Geschichte und Technik über Astronomie, Forschung im Allgemeinen und Speziellen bis hin zu Mathematik und Naturwissenschaften. Ich gehe also davon aus, dass für (fast) alle meiner – sicherlich hauptsächlich technisch interessierten – Besucher etwas dabei sein dürfte. Ihr könnt darüber hinaus auch neue Vorschläge einreichen.
Da mir die Vermittlung von Wissen und das Gespräch über wissenschaftliche Erkenntnisse persönlich äußerst wichtige Angelegenheiten sind, würde ich mich sehr freuen, wenn ihr etwas Passendes findet und die Seite(n) weiterempfehlt. Der Vollständigkeit wegen möchte ich abschließend noch kurz darauf hinweisen, dass ich mit den genannten Seiten in keiner weiteren Verbindung außer als Zuhörer einiger Podcasts stehe.
Hintergrundaufgaben unter ASP.NET ausführen
Im Vergleich zu manch anderen Laufzeitumgebungen für Web-Anwendungen ist es bei ASP.NET auch hier recht einfach, Aufgaben im Hintergrund (beispielsweise über separate Threads) auszuführen. Obwohl das grundsätzlich jederzeit sehr einfach – abgesehen von den inhärenten Schwierigkeiten, die Nebenläufigkeit mit sich bringen kann – möglich ist, ist das einfache Vorgehen, wie man es aus dem Desktop-Bereich kennt, fehleranfällig.
Im einfachsten Fall würde man asynchron per
Bereits seit längerer Zeit werden daher u. a. die beiden Methoden
Im einfachsten Fall würde man asynchron per
Task.Run(…)
(als mit häufig genutzten Standardwerten vorbelegte Abkürzung für Task.Factory.StartNew(…)
) zur Verwendung des Standard-Thread-Pools oder manuell per Thread
-Klasse arbeiten. Dies ist jedoch insofern problematisch, als dass die ASP.NET-Anwendungsdomäne davon nicht benachrichtigt wird und daher beispielsweise einerseits auf die Beendigung des Vorgangs nicht gewartet und andererseits auf das Herunterfahren des Arbeitsprozesses nicht reagiert werden kann.Bereits seit längerer Zeit werden daher u. a. die beiden Methoden
RegisterObject
und UnregisterObject
der HostingEnvironment
-Klasse zur Verfügung gestellt, deren Verwendung jedoch etwas umständlich ist und auf Grund neuerer Möglichkeiten, die gleich im Anschluss vorgestellt werden, an dieser Stelle nicht weiter ausgeführt werden soll. Wir verwenden stattdessen die seit .NET 4.5.2 verfügbare QueueBackgroundWorkItem
-Methode:
Hintergrundaufgabe hinzufügen
Etwas ungeschickt ist es jedoch, wenn dies beispielsweise in einem separaten Projekt ausgelagert werden soll, um jeweils von einer Desktop- und Web-Anwendung darauf zuzugreifen – außerhalb der ASP.NET-Laufzeitumgebung ist die Verwendung dieser Methode nämlich nicht möglich. Daher stellen wir für diesen Fall eine Alternative zur Verfügung, um zumindest ähnliches Verhalten für alle Anwendungsfälle zur Verfügung zu stellen:
010203
HostingEnvironment.QueueBackgroundWorkItem(cT => { /* Implementierung der Aufgabe */});
Hilfsmethode (inkl. Fallback) implementieren
010203040506070809101112
public static class TaskUtility { public static void DoBackgroundWork( Action<CancellationToken> action, CancellationToken cancellationToken = default(CancellationToken) ) { if(HostingEnvironment.IsHosted) { HostingEnvironment.QueueBackgroundWorkItem(action); } else { Task.Run(() => action(cancellationToken), cancellationToken); } }}
Hilfsmethode verwenden
Alternativ wäre es natürlich auch möglich, nur die eigentliche Aufgabe auszulagern und dann anwendungsspezifisch zu starten. Weiterführende Informationen zur Verwendung des CancellationToken stellt das MSDN insbesondere über die Struktur 010203
TaskUtility.DoBackgroundWork(cT => { /* Implementierung der Aufgabe */});
CancellationToken
und die Klasse CancellationTokenSource
zur Verfügung. ZIP-Archive mit C# (ent-)packen
In einem früheren Beitrag zur (De-)Kompression mit C# hatte ich bereits einen Beitrag zu ZIP-Archiven in Aussicht gestellt. Diese sind praktisch, um Dateien und Verzeichnisstrukturen komprimiert und zusammenhängend speichern und austauschen zu können und werden außerdem auf praktisch jeder Plattform unterstützt. Daher möchte ich mit diesem Beitrag zeigen, wie sich mit C# entsprechende Archive automatisch erstellen lassen.
Das .NET-Framework liefert im Namensraum
Zuerst möchte ich ein paar Möglichkeiten aufzeigen, um ZIP-Archive zu erstellen:
Das .NET-Framework liefert im Namensraum
System.IO.Compression
grundlegende Funktionalität zur Arbeit mit entsprechenden Archiven, auf die wir in diesem Beitrag setzen werden. Darüber hinaus gibt es jedoch eine Vielzahl weiterer Implementierungen (z. B. DotNetZip oder SharpZipLib), welche beispielsweise die Erstellung von passwortgeschützten Archiven ermöglichen und weitere Konfigurationsmöglichkeiten bieten.Zuerst möchte ich ein paar Möglichkeiten aufzeigen, um ZIP-Archive zu erstellen:
Archiv aus bestehendem Verzeichnis erstellen
01
ZipFile.CreateFromDirectory("data", "data.zip");
Archiv aus bestehenden Dateien erstellen
010203040506
using(FileStream fileStream = File.OpenWrite("data.zip")) { using(ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create)) { zipArchive.CreateEntryFromFile("data/a.txt", "a.txt"); zipArchive.CreateEntryFromFile("data/b.txt", "b.txt"); }}
Archiv manuell zusammenstellen
Abschließend möchten wir auf bestehende Archive zugreifen:
010203040506070809
using(FileStream fileStream = File.OpenWrite("data.zip")) { using(ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create)) { ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry("README");
using(StreamWriter streamWriter = new StreamWriter(zipArchiveEntry.Open())) { streamWriter.Write("Hallo Welt!"); } }}
Archiv vollständig entpacken
01
ZipFile.ExtractToDirectory("data.zip", "data");
Archiv einlesen und verarbeiten
Sehr viel mehr Möglichkeiten stehen leider tatsächlich nicht zur Verfügung; für weitergehende Einstellungen gibt es jedoch beispielsweise die bereits erwähnten externen Bibliotheken. Durch die Verwendung von Datenströmen besteht aber grundsätzlich die Möglichkeit, nahezu beliebige Quellen (und Ziele) für Archiv-Einträge heranzuziehen. 01020304050607080910111213141516
using(FileStream fileStream = File.OpenRead("data.zip")) { using(ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read)) { foreach(ZipArchiveEntry zipArchiveEntry in zipArchive.Entries) { // "README" separat berücksichtigen if(zipArchiveEntry.Name == "README") { using(StreamReader streamReader = new StreamReader(zipArchiveEntry.Open())) { // Inhalt einlesen und auf Konsole ausgeben Console.WriteLine(streamReader.ReadToEnd()); } } else { // Eintrag als Datei speichern zipArchiveEntry.ExtractToFile(zipArchiveEntry.Name); } } }}
Project links
-
BitStadt – Stadtportal
Berlin · Hamburg · Amsterdam -
CCC – Fahrplan
Schedules for the CCCongress
Categories / Archive | Übersicht
- PHP functions in C# (136)
- Dictionary (257)
Tags
.NET · ADO.NET · Work · ASP.NET MVC · Blog · C# · Generics · Society · Computer Science · Java · LINQ · Logic · Mathematics · Network · PHP · Project · Security · Software development · Studies · Technics · Theory · Web design · WPF