Laden...

suche Dateien

Erstellt von Loewchen0507 vor 17 Jahren Letzter Beitrag vor 17 Jahren 5.165 Views
Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 17 Jahren
suche Dateien

Hi Leute,

ich bin grade dabei in C# Excel Tabellen auszulesen und diese in eine Datenbank zu schreiben. Alles wunderbar. Aber wo ich keinerlei Idee habe ist folgendes:

Wie kann ich alle dateien in einem bestimmten ordner auslesen?

Zum Beispiel möchte ich wissen wieviele Excel Dateien in dem Ordner C:\temp liegen und die Dateinamen wissen.

Wer kann mir helfen?

Bin für jeden tritt dankbar... oder jeden Denkanstoß

Viele liebe Grüße und danke
Loewchen

738 Beiträge seit 2007
vor 17 Jahren

hi,


System.IO.Directory.GetFiles(path);
System.IO.Directory.GetDirectories(path);

(rekursiv durch alle unterordner gibts fertig nicht, hab' ich aber im Forum hier auch schon mal gesehen, falls du das brauchst)

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo nin,

doch, in .NET 2.0 gehts auch leicht inkl. Unterordner: SearchOption.AllDirectories

herbivore

T
98 Beiträge seit 2007
vor 17 Jahren

och das ist jetzt aber einfach 🙂

Erstmal:

using System.IO;

dann brauchst du noch DirectoryInfo und FileInfo

kleines Beispiel gefällig?


private void getAllExcelFiles()
{
   DirectoryInfo di = new DirectoryInfo("C:\\temp");
   FileInfo[] fi = di.getFiles("*.xls");
   foreach ( FileInfo i in fi )
      richTextBox1.AppendText(i.Name+"\n");
}

B
1.529 Beiträge seit 2006
vor 17 Jahren

in .NET 2.0 gehts auch leicht inkl. Unterordner: SearchOption.AllDirectories

Sollte man trotzdem nicht verwenden, da die Funktion mit einer Exception aussteigt, wenn ein Unterordner nicht geöffnet werden kann.

738 Beiträge seit 2007
vor 17 Jahren

@herbivore und Borg:
danke, das mit den SearchOptions ist mit neu !

@TEry:
so gehts einfacher oder?


foreach (string file in Directory.GetFiles("C:\\temp"))
            {
                 if (file.EndsWith(".xls"))
                    richTextBox1.AppendText(file+Environment.NewLine);
            }

Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 17 Jahren
Peng

Hey,

danke für die vielen Infos...
Da muss ich Euch ja alle mal loben hier in dem Forum... So viele Antworten in so kurzer Zeit hätte ich nicht erwartet...

ich habe mich für die Variante von NIN entschieden...
funktioniert, hat wenig code und ist vollkommen ausreichend...

Aber ich werde mir die anderen Varianten notieren...

Also nochmal dickes danke schön an alle...

LG Loewchen

T
98 Beiträge seit 2007
vor 17 Jahren

ohweh,
was weniger code hat und funktioniert, ist nicht immer das, was brauchbar ist.
Es ist doch einfach ***, sich die Namen der Files in einem Verzeichniss zu holen und dann über die Abfrage if (file.EndsWith ... zu sortieren.
Es ist einzig richtig, sich brauchbare Ergebnisse korrekt über
FileInfo[] fi = di.GetFiles("
.xls")
zu holen.
In Fi.Length findet man die Anzahl der xml Dateien. Man hat über in FileInfo so ziemlich alles geordnet, was man irgendwie brauchen kann. Name, Erstelldatum, Grösse des Files usw...
Aber bitte, ich habe gewarnt! Der Code ist zwar kurz, aber so böse, dass ich ihn nicht mal meinen Feinden zu offerieren wagte.
Was hast du dir nur dabei gedacht, nin, einen solchen Code zu schreiben!
Bestimmt führen viele Wege zum Ziel, aber bei so was kommen mir die Tränen.

Gruss TEry

D
386 Beiträge seit 2007
vor 17 Jahren

Ja, ich wuerde auch direkt Directory/GetFiles die Dateien suchen lassen die ich will


Directory.GetFiles(Pfad, "*.xls")

Der Rest des Beitrags war pathetisch und hat mir auch die Traenen in die Augen getrieben. Vor lachen. 😉

Edit: CSharp Code tags..

Pound for pound, plutonium is about as toxic as caffeine when eaten.

T
98 Beiträge seit 2007
vor 17 Jahren
 

List<FileInfo> Files = new List<FileInfo>();
   
public void getFiles(string pfad, string searchFiles)
{
   DirectoryInfo d = new DirectoryInfo(pfad);
   if (pfad != "C:\\System Volume Information")
   {
      FileInfo[] fi = d.GetFiles(searchFiles);
      foreach (FileInfo f in fi)
         Files.Add(f);
      DirectoryInfo[] di = d.GetDirectories("*.*");
      foreach (DirectoryInfo i in di)
         getFiles(pfad + "\\" + i.Name, searchFiles);
    }
}

private void button1_Click(object sender, EventArgs e)
{
   getFiles("C:\\","*.xls");
   foreach (FileInfo fi in Files)
      richTextBox1.AppendText(fi.FullName+" "+fi.CreationTime+"\n");
}

Mal zur Entspannung 🙂
Gruss TEry

D
386 Beiträge seit 2007
vor 17 Jahren

Himmel..


private void button1_Click(object sender, EventArgs e)
{
   foreach (FileInfo fi in Directory.GetFiles(@"C:\", "*.xls")) {    
      richTextBox1.AppendText(fi.FullName+" "+fi.CreationTime+"\n");
   }
}

Spielen wir mal "Suche die Unterschiede in beiden Bildern". 😉

Edit: Gnaa.. Daemlicherweise hab ich da uebersehen, dass tatsaechlich jemand dort eine nicht lokale Variable nutzt. Gefixt.

Pound for pound, plutonium is about as toxic as caffeine when eaten.

T
98 Beiträge seit 2007
vor 17 Jahren

hi DarKlajid,
also du wolltest sicher schreiben:


foreach (string s in Directory.GetFiles(@"C:\Temp", "*.xls")) 
   richTextBox1.AppendText(s+"\n");

finde ich auch weitaus besser als nin's, variation 🙂

Gruss
TEry

D
386 Beiträge seit 2007
vor 17 Jahren

Richtig, danke.

Pound for pound, plutonium is about as toxic as caffeine when eaten.

Loewchen0507 Themenstarter:in
292 Beiträge seit 2006
vor 17 Jahren

hi Leute,

ich habe es so umgesetzt:


           FileInfo[] fi;

            if (pfad != "C:\\System Volume Information")
            {
                fi = d.GetFiles("*.xls");
            }

            for (int z = 0; z < fi.Length; z++)
            {
                Test2.Items.Add(fi[z].Name);

                ...

            }

soweit so gut...
danke für eure hilfe...

Loewchen

T
98 Beiträge seit 2007
vor 17 Jahren

hi,
wo bitte finde ich für:
"C:\System Volume Information"
die Parameter die mir sagen, das der Zugriff auf dieses Directory verweigert w wird? Die Stringabfrage finde ich persönlich ein Schönheitsfehler ...

Gruss
TEry

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo TEry,

das einzig sinnvolle ist, die Exception zu fangen.

herbivore

T
98 Beiträge seit 2007
vor 17 Jahren

hi herbievore,

ich nehme mal an das geschützte Verzeichnise dieselben Kürzel tragen die ich gefunden habe. Insofern beschränkt sich die Abfrage dann nicht nur auf
ein specielles Verzeichnis:


using System.IO;

List<FileInfo> Files = new List<FileInfo>();
   
public void getFiles(string pfad, string searchFiles)
{
  DirectoryInfo d = new DirectoryInfo(pfad);
  {
    DirectorySecurity dli = d.GetAccessControl();
    string s= dli.GetSecurityDescriptorSddlForm(AccessControlSections.Access);
    if (s.IndexOf("P(A;OICI;FA;;;SY") == -1)
    {
       // und um noch völlig sicher zu gehen, obschon eigentlich überflüssig ...
       try
       {
         FileInfo[] fi = d.GetFiles(searchFiles);
         foreach (FileInfo f in fi)
           Files.Add(f);
         DirectoryInfo[] di = d.GetDirectories("*.*");
         foreach (DirectoryInfo i in di)
         getFiles(pfad + "\\" + i.Name, searchFiles);
       }
       catch (System.UnauthorizedAccessException e)
       {
          richTextBox1.AppendText(e.Message + "\n");
       }
    }
  }
}

private void button1_Click(object sender, EventArgs e)
{
   getFiles(@"C:\","*.xls");
   foreach (FileInfo fi in Files)
      richTextBox1.AppendText(fi.FullName + " length " + fi.Length.ToString()+ "\n");
   richTextBox1.AppendText("Suche beendet\n");
}

Nur es stört mich schon gewaltig, das ich nur über eine Exception derart geschütze Verzeichnise ermitteln kann?! 🙁
Wo speichert den das Dateisystem diese Daten? Weiss jemand vielleicht etwas, das ich nicht weiss, oder schlicht nicht fand?

Danke herbievore, aber try catch ist eine Möglichkeit, aber die letzte, die man anwenden sollte.

Gruss
TEry

D
386 Beiträge seit 2007
vor 17 Jahren

Zwei Fragen:

1)
Warum hast du schon wieder eine void Methode die eine (nicht uebergebene) Variable modifiziert? Wozu soll das gut sein und was spricht gegen einen sinnvollen Rueckgabewert?

2)
Warum ist Exceptionhandling das letzte was man machen sollte? Ich halte es fuer weitaus besser/sinnvoller/schoener als deine kryptischen "Magic Numbers", die kein Mensch nachher mehr begreift.

Pound for pound, plutonium is about as toxic as caffeine when eaten.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo TEry,

nein, try/catch ist hier sinnvoll und das einzig richtige! Das ist wie bei File.Exists. Wenn man das abfragt und danach die Datei öffnen will, kann sie schon wieder weg sein. File.Exists vor dem Öffnen von Dateien abzufragen, bringt gar nichts. Das einzig sinnvolle ist versuchen die Datei zu öffnen und die mögliche Exception zu fangen. Bei Zugriffsberechtigungen ist das das gleiche. Die können sich zwischen dem Abfragen und dem Zugriff ändern. Deshalb zugreifen und die mögliche Exception fangen. try/catch ist also die bevorzugte Möglichkeit für diese Art Problem!

herbivore

T
98 Beiträge seit 2007
vor 17 Jahren

hi herbievore,
naja wenn das wirlich die bevorzugte Lösung für das Problem ist, werde ich diese wohl anwenden müssen.

hi DarKlajid,
wenn du recht hinsiehst, habe ich deine sogenannte "Magic Number" aus:
GetSecurityDescriptorSddlForm

Dieser Kürzel stand als Ergebniss für: "C:\System Volume Information". Und ich frage mich langsam, ob das überhaupt ein Verzeichniss ist und nicht eher eine Art Drive.

zum void kann ich nur sagen, das ich nichts zurückgebe, wenn ich das nicht unbedingt muss. Und in diesem Fall sehe ich keinen Sinn was zurückzugeben ...

Schreib doch bitte eine Verbesserung, wenn dir mein code missfällt 🙂

Gruss TEry

ps. die grössten Kritiker sind jene Menschen, von denen du zwar am meisten lernen wirst, aber die du leider nie so achten wirst, wie sie es verdient hätten ...

D
386 Beiträge seit 2007
vor 17 Jahren

TEry:
Eine "Magic Number" ist eine Konstante/ein Literal, dessen Wert oft willkuerlich und schwer verstaendlich erscheint. In deinem Fall waere das nicht der Aufruf der GetSecurityDescriptorSddlForm Methode (obwohl es nach herbivore und mir ja nicht noetig ware), sondern der String "P(A;OICI;FA;;;SY". Den, mit Verlaub gesagt, kein Schwein auf Anhieb verstehen wird. Das ist nicht gerade sprechend fuer "Dieses Attribut bedeutet vermutlich (..), dass ein Zugriff eine Exception generieren wuerde".

Eine schnelle Suche ergibt uebrigens, dass dieses Verzeichnis die Backups des Systemwiederherstellungsdienstes enthaelt.. Und auch jede Menge Hinweise wie man doch auf das Verzeichnis zugreifen kann oder es sogar loeschen, falls gewollt.

Zum Thema des Codes oben: Was du dort machst ist fuer mich ein eindeutiger Seiteneffekt. Du hast irgendwo eine Variable deklariert, du hast eine Methode an anderer Stelle und jedes Mal wenn man die Methode aufruft wird in der Variable gefrickelt. Das ist
a) unschoen und ggf. problematisch (Stell dir zwei getFiles() Aufrufe gleichzeitig vor)
b) nicht intuitiv
c) komplett unnoetig

Meine "Verbesserung" steht schon hier und du selbst hast noch einen Fehler von mir korrigiert..

Pound for pound, plutonium is about as toxic as caffeine when eaten.

T
98 Beiträge seit 2007
vor 17 Jahren

Wenn es jetzt noch Sinn machen würde, könnte man an der Magic Number zwar noch etwas basteln. Aber da es lt. Reverenz eh keinen Sinn macht, belasse ich es mal dabei. Insofern war es wirklich unschön.

Inwieweit ich jedoch die gesammte Festplatte C im Visier habe und darin alle .xls Dateien in einem einzigen Array speichere, habe ich mir wahrscheinlich etwas zu viel vorgenommen um eine schöne Lösung, oder gar Referenzlösung anzubieten.

Ich für meinen Teil, habe mir jetzt genug Arbeit mit dem Problem gemacht; lehne mich zurück, und fals diese Problemetik jemand besser in den Griff bekommt, werde ich klatschen und rufen: Hurra.

Ansonst
Grüsse und frohes coden
TEry

T
98 Beiträge seit 2007
vor 17 Jahren

Ok ich hab es nun mit einem Thread versucht und einer Classe. Das der Thread und die Classe global sind, missfällt mir auch, aber ich finde im Moment einfach keine bessere Lösung zu diesem Problem. Aber es geht bestimmt besser ... keine Frage!

Ich hoffe die 3 Buttons, 2 textBoxes und das Ergebnissfenster sind genug deutlich formuliert.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.ComponentModel;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Thread searchDirectoryThread;
        myDirectory myD;

        public class myDirectory
        {
            private List<FileInfo> gefundeneDateien = new List<FileInfo>();
            public void clear()
            {
                if (this.gefundeneDateien != null)
                    this.gefundeneDateien.Clear();
            }
            public int getSearchFilesCount()
            {
                if (this.gefundeneDateien != null)
                    return this.gefundeneDateien.Count;
                else
                    return 0;
            }

            public bool searchDirectory(string pfadTemp, string searchPattern)
            {
                bool result = true;
                DirectoryInfo di = new DirectoryInfo(pfadTemp);
                try
                {
                    FileInfo[] fi = di.GetFiles(searchPattern);
                    foreach (FileInfo f in fi)
                       this.gefundeneDateien.Add(f);
                    DirectoryInfo[] d = di.GetDirectories();
                    if (d.Length == 0)
                        result = false;
                    foreach (DirectoryInfo dTemp in d)
                       searchDirectory(pfadTemp + @"\" + dTemp.Name, searchPattern);
                }
                catch
                {
                    result = false;
                }
                return result;
            }
            public List<FileInfo> getFiles()
            {
                return this.gefundeneDateien;
            }
        }

        private void ThreadDirectorySearch()
        {
            if (myD == null)
                myD = new myDirectory();
            else
                myD.clear();
            string pfad = @textBox_pfad.Text;
            string searchPattern = textBox_searchPattern.Text;
            while (!myD.searchDirectory(pfad, searchPattern))
            {
            }
            searchStart = false;
            MessageBox.Show(myD.getSearchFilesCount().ToString() + " Files gefunden");
            this.searchDirectoryThread.Abort();
        }

        private bool searchStart = false;

        private void button_search_Files_Click(object sender, EventArgs e)
        {
            if (!searchStart)
            {
                this.searchDirectoryThread = new Thread(new ThreadStart(ThreadDirectorySearch));
                this.searchDirectoryThread.Start();
                searchStart = true;
            }
        }

        private void button_show_Files_Click(object sender, EventArgs e)
        {
           listBox1.Items.Clear();
           foreach (FileInfo f in myD.getFiles())
                    listBox1.Items.Add(f.FullName);
        }

        private void button_search_Files_Exit_Click(object sender, EventArgs e)
        {
            try
            {
                this.searchDirectoryThread.Abort();
            }
            catch
            {
            }
            MessageBox.Show(myD.getSearchFilesCount().ToString() + " Files gefunden");
            searchStart = false;
            listBox1.Items.Clear();
            foreach (FileInfo f in myD.getFiles())
                listBox1.Items.Add(f.FullName);
        }
    }
}

Gruss TEry