Frage von jundo324, 112

Mit C# Dateien suchen, was habe ich falsch gemacht?

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;      

private void suchenachliedern(object sender, RoutedEventArgs e)
            {
    
                listBox1.Items.Clear();
                string[] files = Directory.GetFiles(@"D:");
                string[] dirs = Directory.GetDirectories("D:");
    
                foreach (string file in files)
                {
                    listBox1.Items.Add(Path.GetFileName(file));
                }
    
               foreach (string dir in dirs)
                {
                   listBox1.Items.Add(dir);
                }
    
             
    
    
        }

Das ist mein Code, um auf "D" nach allen Dateien und Ordnern zu suchen. Allerdings funktioniert das nicht (auf D sind einige Dateien). Wenn ich aber den Pfad zu C also meiner Systemplatte ändere, findet er einige Dateien allerdings nur irgendwelche Systemdateien mit .dll und so. Ändere ich den Pfad zu C:\Users\Alex\Pictures\MyDir findet er auch nichts. Wo ist der Fehler an dem Code? Könnt ihr mir sagen wie ich das beheben kann? Danke schonmal.

Antwort
von PWolff, 70

Du listest irgendwie alle Dateien im Hauptverzeichnis auf und die Unterordner listest du auf anstatt sie zu betreten.

Such mal im "Object Browser" nach GetFiles. Die Funktion System.IO.Directory.GetFiles hat mehrere Signaturen (Überladungen). Vielleicht findest du eine Überladung (und einen Wert für das Optionen-Argument), die für deine Zwecke besser passt.

Wenn du einen Namen inkl. Pfad hast, kannst du mit System.IO.Path.GetFileName(fullyQualifiedName) den Dateinamen ohne Pfad extrahieren.

Kommentar von jundo324 ,

naja er listet so wie es sehe alle Dateien im Ordner des Projektes auf, denn ich kopiere eine Datei hinein und beim Suchen finde ich sie dann auch in der ListBox. Weist du wie ich ihn dazu bringen aknn die gesammte Platte C und auch die Platte D zu durchsuchen?

Kommentar von PWolff ,

Laufwerke durchsuchen:

for (char c='A'; c<='Z'; c++) {
var drvInfo = new System.IO.DriveInfo(c.ToString());
if (!drvInfo.IsReady) {continue;};

// Hier die Dateien im Laufwerk drvInfo auslesen
};

Dateien auflisten geht im Prinzip so:

var dirInfo = drvInfo.RootDirectory;
var files = dirInfo.GetFiles("*.mp3", System.IO.SearchOptions.AllDirectories);
listBox1.Items.AddRange(files);

sobald die Suche aber auf einen Ordner stößt, in den sie nicht hineinsehen darf, kommt es zu einem Laufzeitfehler. Das betrifft insbesondere das Systemlaufwerk.

Da muss man wohl selber eine rekursive Funktion schreiben, die diesen Fehler ordnerweise abfängt.

(siehe https://msdn.microsoft.com/de-de/library/bb513869.aspx - hier findest du auch ein einfaches Codebeispiel hierfür)

Kommentar von PWolff ,

Weiterer Tipp vom Profi: gib in kurzen Zeitabständen aus, welcher Ordner gerade durchsucht wird - sonst glaubt der Anwender, das Programm wäre abgestürzt. (Das Durchsuchen von zig Millionen Dateinamen braucht mehrere Minuten.)

Noch besser wäre es, wenn du die Suche "asynchron" ausführen lassen könntest, aber das ist dann schon ein Thema für später.

Kommentar von jundo324 ,
private void suchenachliedern(object sender, RoutedEventArgs e) { listBox1.Items.Clear(); // string[] files = Directory.GetFiles(@"C:"); // string[] files = Directory.GetFiles(@"D:\", "*", SearchOption.AllDirectories); //// string[] files = Directory.GetFiles(@"C:", "*", SearchOption.AllDirectories); //string[] dirs = Directory.GetDirectories(@"D:", "*"); // foreach (string file in files) { // listBox1.Items.Add(Path.GetFileName(file)); } // foreach (string dir in dirs) { // listBox1.Items.Add(dir); } GetAllFiles(@"C:\"); } private static void GetAllFiles(string sDir) { foreach (string dir in Directory.GetDirectories(sDir)) { try { foreach (string File in Directory.GetFiles(dir, "*.MP3")) { string mp3File = Path.GetFileName(File); listBox1.Items.Add(mp3File); } GetAllFiles(dir); } catch (Exception Error) { // Console.WriteLine(Error.Message); } }

jetzt habe ich diesen Code, allerdings sagt er: Für das nicht statische Feld, die Methode oder die Eigenschaft "MainPage.listBox1" ist ein Objektverweis erforderlich. Wie kann ich so ein Objektverweis erstellen? habt ihr ne Lösung?

Kommentar von PWolff ,

Sorry, hab ne Weile gebraucht, um das MainPage zu bemerken.

ASP.NET? Ich war von einer Windows-Desktop-Anwendung ausgegangen. (Das ist das, womit ich mich am meisten beschäftige.)

Ersetze "listBox1" durch den Namen, den die Auswahlliste auf deiner Webform hat.

Kommentar von jundo324 ,

ne ist ne Windows Universal App
sry aber was meisnt du mit Auswahlliste auf deiner Webform?

Kommentar von PWolff ,

Der Name "MainPage" deutet für mich auf eine Webanwendung hin.

Steuerelemente wie Eingabefelder, Buttons, Auswahllisten u. ä. befinden sich für gewöhnlich innerhalb von form-Tags in einer HTML-Seite. Deshalb Webform.

(Desktop-Anwendungen verwenden Fenster, die im C#-Jargon forms genannt werden, von daher können wir den Begriff Form so oder so verwenden.)

Welche Steuerelemente (Controls) hast du auf der Form?

Kommentar von jundo324 ,

achso ok ah ich habe einen Button und eine listBox1

Kommentar von PWolff ,

Dann probier mal, nur listBox1 zu schreiben, ohne irgendetwas davor.

Kommentar von jundo324 ,

also ich habe das hier an Code :
http://cox.bplaced.net/111.png
http://cox.bplaced.net/222.png
und da ist halt der Fehler

Kommentar von PWolff ,

Ach so, du hast die Funktionen als static deklariert - da sind dann nur die Variablen bekannt, die ebenfalls static sind, sich also auf die ganze Klasse beziehen.

(Sorry, mein Gehirn kriegt es meistens nicht richtig hin, Meldungen und andere Dinge außerhalb des üblichen Kontextes zu erkennen.)

Entweder nimmst du das static weg (und benennst die Funktion besser um in listBox1Fuellen oder ähnlich), oder du machst aus dem void ein string[] oder ein List<string> und lässt die Funktion ein Array oder eine Liste von Strings zurückgeben; dieses Array liest du dann in die ListBox ein. Die 2. Möglichkeit ist besser wiederverwertbar, weshalb ich sie empfehlen würde.

Antwort
von jundo324, 30
private void suchenachliedern(object sender, RoutedEventArgs e) { listBox1.Items.Clear(); // string[] files = Directory.GetFiles(@"C:"); // string[] files = Directory.GetFiles(@"D:\", "*", SearchOption.AllDirectories); //// string[] files = Directory.GetFiles(@"C:", "*", SearchOption.AllDirectories); //string[] dirs = Directory.GetDirectories(@"D:", "*"); // foreach (string file in files) { // listBox1.Items.Add(Path.GetFileName(file)); } // foreach (string dir in dirs) { // listBox1.Items.Add(dir); } GetAllFiles(@"C:\"); } private static void GetAllFiles(string sDir) { foreach (string dir in Directory.GetDirectories(sDir)) { try { foreach (string File in Directory.GetFiles(dir, "*.MP3")) { string mp3File = Path.GetFileName(File); listBox1.Items.Add(mp3File); } GetAllFiles(dir); } catch (Exception Error) { // Console.WriteLine(Error.Message); } }

jetzt habe ich diesen Code, allerdings sagt er: Für das nicht statische Feld, die Methode oder die Eigenschaft "MainPage.listBox1" ist ein Objektverweis erforderlich. Wie kann ich so ein Objektverweis erstellen? habt ihr ne Lösung?

Expertenantwort
von FaronWeissAlles, Community-Experte für Computer, 78
string[] files = Directory.GetFiles(@"D:\","*",SearchOption.AllDirectories);


Kommentar von Dultus ,

Genauso würde ich es auch schreiben^^(War gerade dabei xD). der string, der die Files anzeigen soll, war nur nicht definiert und hatte daher nur Standard-Windows files ausgelesen^^.

MfG

Kommentar von jundo324 ,

Oh, Danke ^^

es gibt aber noch ein Problem u zwar sucht er denke ich mal nur in dem Ordner wo das Programm gespeichert ist, da er jetzt Bilder... von dem Programm findet aber nicht die Dateien die ich zb im Bilder Ordner habe, was er aber tun soll.



Kommentar von FaronWeissAlles ,

es gibt aber noch ein Problem u zwar sucht er denke ich mal nur in dem Ordner wo das Programm gespeichert ist

das würde er machen wenn man einen relativen Pfad angibt (ohne Laufwerksbuchstaben). Hier ist aber ein absoluter Pfad angegeben und dann sucht er in D:\ und allen Unterordnern

Kommentar von jundo324 ,

das würde er machen wenn man einen relativen Pfad angibt (ohne Laufwerksbuchstaben). Hier ist aber ein absoluter Pfad angegeben und dann sucht er in D:\ und allen Unterordnern

versteh mich nicht falsch also er sucht die Dateien in D und findet nichts. Wenn ich den Pfad auf C lege sucht er und findet auch was aber nur Dateien die zu der App/Anwendung gehören. also die Dateien sind auch nicht direkt auf C sondern in vielen Unterordnern.
Er soll aber alle Dateien auf dem ganzen PC anzeigen (also eig reicht Laufwerk D aber alle wäre am besten)

Kommentar von PWolff ,

Für alle Laufwerke könnte eine Suche von \\Computername aus funktionieren - das müsste ich jetzt ausprobieren. Alternativ gehst du alle möglichen LW-Buchstaben von A bis Z durch, testest, ob das zugehörige LW existiert und bereit ist und liest dort die Dateien aus.

Kommentar von jundo324 ,

Ok habe ich jetzt mal gemacht also mit anderen Laufwerksbuchstaben allerdings zeigt er nur Bei C etwas an nicht bei D obwohl da auch Dateien drin sind





private void suchenachliedern(object sender, RoutedEventArgs e)
{

listBox1.Items.Clear();
// string[] files = Directory.GetFiles(@"C:");
// string[] files = Directory.GetFiles(@"D:\", "*", SearchOption.AllDirectories);
string[] files = Directory.GetFiles(@"D:", "*", SearchOption.AllDirectories);
string[] dirs = Directory.GetDirectories("D:");


foreach (string file in files)
{
listBox1.Items.Add(Path.GetFileName(file));

}

foreach (string dir in dirs)
{
listBox1.Items.Add(dir);
}
}
Kommentar von jundo324 ,

Ok habe ich jetzt mal gemacht also mit anderen Laufwerksbuchstaben allerdings zeigt er nur Bei C etwas an (bei C auch nur Dateien die im App Ordner liegen also nicht Dateien die auf dem Desktop liegen) und auch nicht bei D (bei D sogar überhaupt nichts) obwohl da auch Dateien drin sind.

private void suchenachliedern(object sender, RoutedEventArgs e)       
{
listBox1.Items.Clear();
// string[] files = Directory.GetFiles(@"C:");
// string[] files = Directory.GetFiles(@"D:\", "*", SearchOption.AllDirectories);
string[] files = Directory.GetFiles(@"D:", "*", SearchOption.AllDirectories);
string[] dirs = Directory.GetDirectories("D:");
foreach (string file in files)
{
listBox1.Items.Add(Path.GetFileName(file));
}
foreach (string dir in dirs)
{
listBox1.Items.Add(dir);
}
}

Keine passende Antwort gefunden?

Fragen Sie die Community