Nicht genutzen Laufwerksbuchstaben herausfinden



  • Blacky666 schrieb:

    Hey,

    ich habe eine Methode geschrieben, die einen nicht genutzen Laufwerksbuchstaben als string zurückgibt. (z.B A: ) Wenn kein Laufwerksbuchstabe frei ist, wird ein string "No assigned network letter" zurückgegeben.

    Die Rückgabe von "No assigned network letter" ist ganz übel. Es ist ein allgemeines Problem, v.a. auch bei Exceptions zu beobachten, dass viele Programmierer nur mit strings hantieren.
    Was soll man damit anfangen?

    Es wurden ja schon deutlich bessere Vorschläge gemacht. Wenn Du aber unbedingt bei deinem string als Rückgabewert bleiben willst, dann gib im Fehlerfall wenigstens null zurück. Nicht ideal, aber dann kann der Aufrufer besser drauf reagieren.



  • @ GPC: Danke für dein Code Beispiel. Deine Variante ist auf jedenfall kürzer und übersichtlicher. Nur kenn ich mich leider mit IEnumerable noch nicht aus. Muss mich da erstmal einlesen. Genauso was HashSet bewirkt, weiß ich auch noch nicht.
    In meinem Programm, in dem ich diese Methode nutze, benötige ich nur die Info für einen freien Laufwerksbuchstaben. Grundsätzlich gebe ich dir aber recht, dass es schöner wäre, wenn meine Methode alle freien Laufwerksbuchsteben zurückgibt (sei es in einem Array oder in einer IEnumerable).

    @ µ: Das habe ich mir auch schon gedacht, dass das sehr ungünstig ist. Leider ist mir kein anderer Ausweg mit meiner Begrenzten C# Erfahrung eingefallen. 🙄 Ok das ich NULL zurückgeben könnte, hätte mir schon einfallen können... 😃



  • Na ja, also die "n00bige"-Variante sähe dann wohl so aus:

    using System.Linq;
    
    //Aus LinqPAD kopiert
    void Main()
    {
    	foreach (var unassignedLetter in getUnassignedNetworkLetter()) {
    		Console.WriteLine(unassignedLetter);
    	}
    }
    
    // Define other methods and classes here
    private IEnumerable<string> getUnassignedNetworkLetter() {
    	string[] assignedLetters = Directory.GetLogicalDrives();
        List<string> freeLetters = new List<string>();
    
    	char c = 'A';
    	while (c <= 'Z') {
    		string letter = c + @":\";
    		if (assignedLetters.Contains(letter) == false)
    			freeLetters.Add(letter);;
    		++c;
    	}
    
        return freeLetters;
    }
    

    Das ist jetzt nicht mehr ganz so cool, aber immer noch cool genug 🤡
    Ein HashSet (Oder nur "Set") ist eine Datenstruktur, die du dir mal genauer anschauen solltest. Die Wikipedia hat sicher einen Artikel. 🙂



  • private static IEnumerable<Char> getUnassignedNetworkLetter()
    {
      List<Char> unassigned = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToList<Char>();
    
      foreach (String drive in Environment.GetLogicalDrives())
        unassigned.Remove(drive[0]);
    
      return unassigned;
    }
    


  • fkaskd schrieb:

    private static IEnumerable<Char> getUnassignedNetworkLetter()
    {
      List<Char> unassigned = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToList<Char>();
    
      foreach (String drive in Environment.GetLogicalDrives())
        unassigned.Remove(drive[0]);
    
      return unassigned;
    }
    

    Wird nicht funktionieren, da GetLogicalDrives es mit + 😕 zurück gibt.
    Siehe: http://msdn.microsoft.com/en-us/library/system.environment.getlogicaldrives.aspx

    D.h. diese Methode gibt alle Laufwerke als unbenutzt zurück 😉



  • Wie wäre es damit?:

    static void Main(string[] args)
    {
        foreach (var drive in GetFreeDriveLetters())
            Console.WriteLine(drive);
    }
    
    private static IEnumerable GetFreeDriveLetters()
    {
        var drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToList<char>().Select(d => d + ":\\").ToList();
        var usedDrives = Environment.GetLogicalDrives();
        drives.RemoveAll(d => usedDrives.Contains(d));
        return drives;
    }
    


  • Ich habe jetzt auch nochmal ein wenig rumprobiert. 🙂 Morgen werde ich mich mal in IEnumeral und HashSet einlesen um eure Codebeispiele richtig zu verstehen.

    private string getUnassignedNetworkLetter()
            {
                string[] assignedNetworkLetters = Directory.GetLogicalDrives();
                char letter = 'A';
    
                while (letter <= 'Z')
                {
                    foreach (string currentCheckDrive in assignedNetworkLetters)
                    {
                        if (currentCheckDrive.Contains(letter) == false)
                            return letter.ToString() + ":";
                        letter++;
                    }
                }
                return null;
            }
    


  • Hallo David,

    der Code funktioniert aber, denn es wird dort ja "drive[0]" (also nur das erste Zeichen) benutzt...



  • Fear teh power of my linq skillz!

    Enumerable.Range((int)'A', (int)'Z' - (int)'A' + 1).Select(i => (char)i + @":\").Except(Directory.GetLogicalDrives())
    

    :p



  • David W schrieb:

    fkaskd schrieb:

    private static IEnumerable<Char> getUnassignedNetworkLetter()
    {
      List<Char> unassigned = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToList<Char>();
    
      foreach (String drive in Environment.GetLogicalDrives())
        unassigned.Remove(drive[0]);
    
      return unassigned;
    }
    

    Wird nicht funktionieren, da GetLogicalDrives es mit + 😕 zurück gibt.
    Siehe: http://msdn.microsoft.com/en-us/library/system.environment.getlogicaldrives.aspx

    D.h. diese Methode gibt alle Laufwerke als unbenutzt zurück 😉

    Nein, wie Th69 schon gesagt hat, funktioniert der Code korrekt. 😉



  • Stimmt, hab das [0] übersehen - Sorry 🙂

    Die ersten beiden Lösungen von GPC finde ich am schönsten, klar geht es kürzer, aber im Sinne der Wartbarkeit und vor allem Übersicht sind diese beiden zu bevorzugen 🙂



  • Ich find die Lösung von fkaskd sehr schön. Durchaus elegant und tut genau das, was man erwartet. Einen Buchstaben (Letter) zurückgeben.

    Insbesondere die while-Schleife in den anderen Codes ist nicht so toll. Hier wäre eine For-Schleife um einiges schöner:

    for (char c = 'A'; c <= 'Z'; ++c)
    {
     // ...
    }
    


  • Flurry schrieb:

    Ich find die Lösung von fkaskd sehr schön. Durchaus elegant und tut genau das, was man erwartet. Einen Buchstaben (Letter) zurückgeben.

    Die Lösung finde ich auch gut, aber sie gibt dennoch eine Sequenz von Buchstaben und nicht nur einen einzelnen zurück 😛

    Insbesondere die while-Schleife in den anderen Codes ist nicht so toll. Hier wäre eine For-Schleife um einiges schöner:

    Das halte ich für eine Geschmacksfrage.. auf mich wirkt die for-Schleife irgendwie "unpassend" 🙂



  • und ich dachte immer wenn A-Z belegt ist geht es bei AA, AB, AC, ... weiter. 😉



  • brzzz schrieb:

    und ich dachte immer wenn A-Z belegt ist geht es bei AA, AB, AC, ... weiter. 😉

    Nicht so viel denken. Windows kennt nur 26 Laufwerkbezeichner 😉


Anmelden zum Antworten