ich möchte euch hier mein QuickIO.NET Projekt vorstellen.
Begonnen hab' ich das ganze ca. 2009 im Rahmen eines Tools um meine NAS-Shares zu visualisieren und immer mal wieder dran rum gebaut.
Anfang dieses Jahres hab ich mich dann intensiv gekümmert und es ganz als Projekt durchgezogen.
Es dient als Erweiterung für den System.IO-Namespace und bietet neben deutlich performanteren Zugriffen auch die Möglichkeit von UNC-Pfaden (Pfadlängen bis 32.767 Zeichen).
Für die Anwendung selbst ändert sich kaum etwas, da ich mich relativ streng an die vorhandenen Außenschnittstellen von System.IO orientiert habe.
Features
Deutliche Performance-Vorteile gegenüber System.IO-Klassen/Methoden (bis zu 30-fach schneller)
Direkte, ungefilterte Aufrufe der Win32 API
Unterstützung von Pfadlängen bis 32768 Zeichen
Transfer-Service: Dateioperationen mit Fortschritts-Information und Condition Monitoring
Modularisierung in Jobs mit Queue-System, Parallel-Unterstützung und Priorisierung. Mit eigenen Implementierungen erweiterbar.
Berechnung von Hashes auf Basis verschiedener Algoriithmen (Sha, MD5..)
Parallel zu System.IO nutzbar + einfache Integration in vorhandenen Code durch Methoden-Ersatzung
Lizenz
Lizenziert ist das ganze als Open Source unter Ms-PL
Verwendung in allen Projekten, egal ob privat oder kommerziell ohne Namensnennung möglich - wär trotzdem nett.
Erst mal Danke für die Arbeit, Mühe und das freie zur Verfügung stellen. Auf so eine Bibliothek habe ich gewartet.
Beim meinem ersten Test (dein Beispiel für "Get subfiles") fliegt eine InvalidPathException:
Fehler
The directory name is invalid
Path=D:\Downloads\IrgendeinFile.zip
StackTrace:
bei SchwabenCode.QuickIO.Internal.InternalQuickIOCommon.NativeExceptionMapping(String path, Int32 errorCode) in c:\_data\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIOCommon.cs:Zeile 147.
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.<EnumerateFiles>d__26.MoveNext() in c:\_data\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs:Zeile 754.
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.<EnumerateFiles>d__26.MoveNext() in c:\_data\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs:Zeile 777.
bei QuickIOTest.Program.Main(String[] args) in d:\Work\QuickIOTest\QuickIOTest\Program.cs:Zeile 16.
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
Dieser Fehler tritt nur auf, wenn ich über alle Ordner (SearchOption.AllDirectories) suchen möchte. Lasse ich die Option weg, funktioniert es.
Hier mein Code:
static void Main(string[] args)
{
var result = QuickIO.EnumerateFiles(@"d:\Downloads", SearchOption.AllDirectories);
foreach (var item in result) // Hier kommt die Exception
{
Console.WriteLine(item);
}
Console.ReadLine();
}
Achja, Win 7, VS 2013, .NET 4.5
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von PuppetMaster2k am .
In der dotnetpro 08/2014 Ausgabe, die am 17. Juli erscheint, schreibt Fabian Deitelhoff einen sehr ausführlichen Artikel (5 Seiten) mit Hintergrundinformationen, Beispielen über QuickIO.NET - ich hoffe positives (kenne den Artikel selbst nicht).
Zu finden auf Seite 68 bis 72
@Abt: Du könntest doch QuickIO abstrahieren, am besten auch sogar so, dass man Azure und S3 abbilden kann. Das hätte ich sehr gerne. Hatte man damit angefangen, aber nie Zeit das richtig zu machen.
malignate, was Du mit abstrahieren meinst weiß ich nicht; kannst Du mir gerne via PN zukommen lassen.
Für Azure hab ich was eigenes (CDN / Blogs und Co).
ich bekomme eine: "FileAlreadyExistException" wenn ich eine Datei die es nicht doppelt gibt, vom Desktop in einen von mir erstellten ordner den es ebenfalls nicht doppeltg gibt, kopiere.
Fehler
Cannot create a File when that file already Exist
QuickIOFileCopyJob job = new QuickIOFileCopyJob (@"C:\Users\****\Desktop\Neuer Ordner\file.mp3", @"C:\Users\****\Desktop\Ordner", observer);
Zu aller erst einmal vielen Dank für die Library. Meine Aufgabe ist es ein ca. 12GB großes File von einem Server auf einen USB Stick kopieren.
Mit File.Copy dauerts über eine Stunde, deswegen war ich auf der Suche nach einer anderen Library. (Per NuGet installiert).
Gleich beim Testen stoße ich da auf einen eigenartigen Fehler:
Es sieht so aus, als würde er nach fehlenden Sourcen suchen.
Nullpointer bei QuickIOTransferFileCopyJob:
Namen, Klassen und Pfade wurden verändert.
QuickIOTransferFileCopyJob copyJob = new QuickIOTransferFileCopyJob(@"\\server\test.ova", @"E:\test.ova", 65535);
copyJob.Started += OnCopyStarted;
copyJob.Progress += OnCopyProgress;
copyJob.Finished += OnCopyFinished;
copyJob.Run(); <- Hier kommt NPE.
Fehler
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.CreateDirectory(QuickIOPathInfo pathInfo, Boolean recursive) in c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs:Zeile 134.
bei SchwabenCode.QuickIO.QuickIODirectory.Create(QuickIOPathInfo pathInfo, Boolean recursive) in c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\QuickIODirectory_Create.cs:Zeile 93.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferFileCopyJob.Implementation() in c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferFileCopyJob.cs:Zeile 109.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferJob.Run() in c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferJob.cs:Zeile 139.
Meine Klasse
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
Wie es aussieht hatte PuppetMaster2k auch ein ähnliches Problem, welches du gleich behoben hast.
Vielen Dank im voraus.
PS.: Mir ist auch ein kleiner Fehler in der API von QuickIO aufgefallen: QuickIO.NET API - QuickIOTransferFileCopyJob
API = Library (Die folgenden Punkte heißen links in der API und rechts in der Library)
Das erste Schau ich mir an, das zweite versteh ich nicht, was Du meinst.
EDIT: Kann das sein, dass Du die Eventhandler meinst? Wenn ja, dann ist das Absicht so.
Die Handler zum abonnieren und die On-Methoden zum Feuern von eigenen Elementen.
In dem angegebenen Beispiel verwendest du folgendes:
copyJob.CopyStarted += OnCopyStarted;
verwendet muss es aber so werden:
copyJob.Started += OnCopyStarted;
Dass gilt für alle meine angegebenen Beispiele. Ich hoffe das ist jetzt verständlich formuliert.
Deine API war vollkommen in Ordnung, ich bezog mich hier nur auf das Codebeispiel.
PS.: Andere Codebeispiele habe ich mir nicht angesehen, bzw. auf Richtigkeit überprüft.
Achso. Auf die Beispiele hatte ich gar nicht geachtet.
Ja das kann schon sein, dass das bei einem Rename nicht beachtet wurde ;-)
Die Events stammen ja aus der QUelle einer Basis-Klasse und werden nur durchgereicht. Hatte ich bestimmt irgendwann angepasst.
EDIT: Kann das sein, dass Dein E:\ nicht existiert?
Das ist die einzige Stelle, die ich hier nicht bedacht habe und ein Null geworfen werden könnte. Alle anderen Tests werden bei mir erfolgreich durchlaufen.
Zukünftigt wird eine PathNotFoundException geworfen.
Mein E:\ war beim Test vorhanden, aber dass ist glaub ich nicht das Problem:
Fehler
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.CreateDirectory(QuickIOPathInfo pathInfo, Boolean recursive) in c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs :Zeile 134.
bei SchwabenCode.QuickIO.QuickIODirectory.Create(QuickIOPathInfo pathInfo, Boolean recursive) in
c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\QuickIODirectory_Create.cs:Zeile 93.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferFileCopyJob.Implementation() in
c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferFileCopyJob.cs:Zeile 109.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferJob.Run() in
c:\_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferJob.cs:Zeile 139.
Das Problem dürft sein, dass er ein Verzeichnis/eine Datei nicht findet:
Ich habe hier wieder meine Klassen nicht angefügt und den Stacktrace etwas formatiert
Mein Programm startet vom H:\ Laufwerk (Gemountetes Netzlaufwerk).
Ich weiß als nicht warum die Library versucht auf c:\ zuzugreifen bzw. eine Klasse dort zu suchen.
In meinem c:\ Laufwerk befindet sich kein _data Verzeichnis, auch nicht durch Ändern der "Ordner- und Suchoptionen".
Das C:\ ist mein Compile-Pfad. Dort liegt auf meiner Kiste dieses Projekt.
Das liegt daran, da die PDB, also die Debug-Dateien mit im Paket enthalten sind. So seh ich bei Fehlermeldungen sehr schnell, ob der Code wirklich auf meinen Mist gewachsen ist oder die Leute irgendwelche Anpassungen auf mich abwälzen wollen ;-)
Das hat nichts mit Deiner Kiste oder Deinem Code zutun.
Dein Code ist dieser:
QuickIOTransferFileCopyJob copyJob = new QuickIOTransferFileCopyJob(@"\\server\test.ova", @"E:\test.ova", 65535);
copyJob.Started += OnCopyStarted;
copyJob.Progress += OnCopyProgress;
copyJob.Finished += OnCopyFinished;
copyJob.Run(); <- Hier kommt NPE.
Ich konnte die NullReferenceException nur nachbilden, wenn ich versuche eine Datei direkt auf einem Root-Verzeichnis eines nicht existiertenden Laufwerk zu speichern.
Sprich bei E:\ordner\test.ova wäre der Fehler nicht aufgetreten sondern es hätte eine saubere Exception gegeben.
Wie gesagt; dieser Fall ist jetzt behoben. Suggeriert aber zeitgleich das Du es auf einem Verzeichnis versucht hast, die dieser Fehlerquelle entspricht.
Wenn dies nicht der Fall ist, dann bitte ich Dich den Quellcode von QuickIO.NET zu laden und mal den Debugger anzuwerfen und zu schauen, wo genau die Exception auftritt; also Datei und Zeile.
Hier greifst du auf parent zu, obwohl es auf null zeigt. Dass wird mit jeder Datei passieren,
die du direkt auf das Rootverzeichnis eines beliebigen Laufwerks kopieren willst.
Edit: Datei: Internal\InternalQuickIO.cs
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von xpuehrinq am .
Ich konnte die NullReferenceException nur nachbilden, wenn ich versuche eine Datei direkt auf einem Root-Verzeichnis eines nicht existiertenden Laufwerk zu speichern.
Vorhanden war das Laufwerk aber, Deswegen war mir das ganze jetzt nicht so klar.
Die Events verwenden im gleichen Thread ausgeführt wie das eigentliche Kopieren.
Der Ablauf ist also:
- Copy Chunk
- Event-Abarbeitung
- Copy Chunk
- Event-Abarbeitung
- ....
Die Ausführung wird also leider derzeit gebremst.
Du müsstest also in der Event-Methode die Ausführung deines Codes in einen Task auslagern; also entkoppeln.
Ich hab da irgendwie nicht früher dran gedacht... ;-)
Wäre es auch möglich das man der Funktion ein eigenes Objekt übergeben kann,
auf das man dann wieder in den Events zugreifen kann (wie bei den WebClient().DownloadFileAsync()).
Ich weiß nicht, was Du meinst oder tun willst.
PS: Ach Du meinst das, was WebClient als token(object) deklariert?
Ich seh da zwar kein Anwendungsfall; aber ich schau mal, ob ich da was typisiertes rein bekomme - Object eher nicht ;-)