Dateinamen einzeln auslesen

Hey, momentan lasse ich mir die Namen aller Dateien im Verzeichnis ausgeben.
Ich würde aber gerne nur den Namen der Datei an erster Stelle , zweiter Stelle etc. ausgeben lassen, sodass ich nacher dann mit einer for-schleife alle Namen zum weiterverarbeiten bekomme :slight_smile:

    {
        File folder = new File(path);
        for( File file : folder.listFiles() )
        {
            System.out.println( file.getName() );

        }
        
    }```


Kann gelöscht werden habs selber gelöst.
Falls interesse besteht:

public String name(int i) throws NoSuchElementException
{
File folder = new File(path);
for( File file : folder.listFiles() )
{
filename.add(file.getName()); // Liste mit den namen aller Dateien

    }
    return filename.get(i);
}

Mit file.getName() bekommst du sozusagen den Dateinamen.

Aber deine Liste sollte fileName****s**** file_name****s**** oder Ähnliches heißen.

Jeder Methodenaufruf geht auch alle Files durch, das geht (asymptoisch) von linear zu quadratisch.

Sehr sinnvolle Methode. Bei jedem Aufruf wird der komplette Verzeichnisinhalt IMMER WIEDER geaddet… Fällt das Dir nicht auf?

Im Übrigen ist das Zwischenspeichern in einer Liste überhaupt nicht nötig. Die Methode listFiles() gibt Dir einen Array zurück. Da kann man auch mit index drauf zugreifen.
return folder.listFiles()**.getName();

Ja, aber der Ansatz ist schon gut. Es gibt keine festgelegte Reihenfolge für list() oder listFiles(). Auch keine Methode, der man Visitor oder übergeben oder die Iterator zurückgibt, sondern nur komplette Dateiliste. Dann muss man “zwischenspeichern”.

Mache das so:

  1. gib alle Dateien und Dateinamen,
  2. sortiere nach deinem Kriterium,
  3. gebe einen Iterator zurück.

Die Methode wird einmal aufgerufen beim start des Programmes.
Das Zwischenspeichern ist in sofern nötig, weil ich die Namen später noch Brauche :wink:

Die Idee mit dem Index i ist komisch:

There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.

Die Liste scheinst du ja außerhalb zu erstellen. Eigentlich ist das nicht sehr hübsch so. Denn deine Mehtode macht zweierlei Dinge:

  1. Befüllung der Liste

  2. Rückgabe des ersten Namens in der Liste

Gegenvorschlag:


        .... 
        filenames = readFilenames(path); // im Konstruktor
        String file48 = getFilename(47);
        .... 
    

    public static List<String> readFilenames(final String path) {
        List<String> filenames = new ArrayList<>();
        File folder = new File(path);
        for (File file : folder.listFiles()) {
            filenames.add(file.getName());
        }
        return filenames;
    }

    public String getFilename(final int index)
        return filenames.get(index);
    }

2teres auf keinen Fall. file_names verstößt in Java gegen die Naming Conventions (siehe meine Signatur). Und da es hier um „Filenames“ geht, braucht man kein UpperCamelCase lowerCamelCase zu erzwingen. Ein einfaches filenames wäre da schon in Ordnung.

@TO: Ansonsten sehe ich das wie nillehammer. Mit der Liste machste du dir nur Mehrarbeit die sich nicht lohnt. Nutze einfach das Files-Array, welches dir listFiles() zurück gibt (kannst dir ja auch in einer Membervariablen merken) und gut ists. Dann haste vllt sowas:

    private File[] files;
    
    public MyFolderReader() {
        readFiles();
    }
    
    private void readFiles() {
        files = new File("C:\\MEIN\\PFAD\\ZUM\\ORDNER").listFiles();
    }
    
    public String getFile(int index) {
        return files[index].getName();
    }
}```

Also Reihenfolge wird nicht garantiert, Liste sollte “außerhalb” nur einmal erstellt werden, und Kleinbuchstaben oder lowerCamelCase, Tomate - das ist kein Trollen.
Je nachdem, ob man Englis©h betrachtet - wie auch immer, aber UpperCc false.

[quote=CyborgBeta]Also Reihenfolge wird nicht garantiert, Liste sollte “außerhalb” nur einmal erstellt werden, und Kleinbuchstaben oder lowerCamelCase, Tomate - das ist kein Trollen.
Je nachdem, ob man Englis©h betrachtet - wie auch immer, aber UpperCc false.[/quote]

Schreib mal ganze Sätze. Nach dem 20ten mal lesen hab ichs glaub z.T entziffern können (zumindest den Teil mit UpperCamelCase). Ja das war natürlich Schwachsinn. Ich meinte natürlich (wie du richtig erkannt hast) lowerCamelCase.

listFiles() gibt die Rückgabe-Liste nicht nach einem Kriterium sortiert zurück, sondern sie kann sortiert sein, muss sie aber nicht. Whrs. ist das system-, plattform- oder runtime-spezifisch. Wie soll man det genauer beschreiben, det funkt nicht. Wie Variablennamen geschrieben werden sollten usw. Und das nicht jedes mal eine Liste erstellt werden soll, sondern z. B. Attribut oder Iterator. Vielleicht verstehe ich auch was falsch. Wir brauchten mehr Code, um weiterhelfen.
Sry, heute ist schwer, vollständige/vernünftige Sätze, du kennst das doch von mir.

Hier einmal der ganze QuellCode dadurch wirds natürlich bisschen unübersichtlicher :slight_smile:
Vllt werden Teile aus http://forum.byte-welt.net/java-forum-erste-hilfe-vom-java-welt-kompetenz-zentrum/java-grundlagen-f-r-anf-nger-und-umsteiger-java-se-/13317-file-item-als-klasse-modellieren.html erkannt.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.NoSuchElementException;

import java.util.List;
import java.util.ArrayList;

public class Loader
{

    private String path;
    private String name;
    private String quote; 
    private int cost;
    private int quantity; 
    private int quality;
    static List<Item> gameItems = new ArrayList();
    private List<String> filename = new ArrayList();

    public void main()throws FileNotFoundException // "Objekt" Laden mit dem Pfad als xpath + Name der Datei aus der Liste mit index i
    {
        for(int i = 0; i < zaehler();i++)
        {
            addItem(name(i));
        }
    }

    public Loader(String xpath) // Pfad der Dateien
    {
        this.path = xpath;
    }   

    private int zaehler() // Anzahl der Dateien im Ordner
    {
        File directory = new File(path);
        String[] list = directory.list();
        int count = list.length;

        return count;
    }

    private String name(int i) throws NoSuchElementException // DateiNamen auslesen
    {
        File folder = new File(path);
        for( File file : folder.listFiles() )
        {
            filename.add(file.getName());

        }
        return filename.get(i);
    }

    private Item load(String ItemName) throws FileNotFoundException
    {
        File file = new File(path, ItemName);

        Scanner sc = new Scanner(file);
        this.name = sc.nextLine();
        this.quote = sc.nextLine();
        this.cost = Integer.parseInt(sc.nextLine());
        this.quantity = Integer.parseInt(sc.nextLine());
        this.quality = Integer.parseInt(sc.nextLine());

        return new Item(this.name,this.quote,this.cost,this.quantity,this.quality);
    }

    private void addItem(String name) throws FileNotFoundException
    {

        this.gameItems.add(load(name));

        System.out.println("["+load(name).getName()+"] loaded.");
    }
}

Dir ist schon klar, dass bei jedem Aufruf von name(i) der gesamte Inhalt des Verzeichnisses erneut an die filename-Liste angehängt wird???

  private void getName()
    {
        File folder = new File(path);
        for( File file : folder.listFiles() )
        {
            filename.add(file.getName());
        }
    }

    private String name(int i) throws NoSuchElementException
    {        
        return filename.get(i);
    }

Besser :slight_smile:

Wenn sich der Verzeichnisinhalt nicht ändert, kann man den Code von getName in den Konstruktor packen (soll ja auch nur einmal aufgerufen werden). Statt der Schleife sollte auch fileName = Arrays.asList(new File(path).list()); gehen.

“gesamte Inhalt des Verzeichnisses erneut” - nicht schlimm, der Flaschenhals ist der user (Benutzereingabe).

Mach das doch so, eine eigene Klasse File:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/**
 * @author CB
 */
public class MyFiles {

    private List<File> files;
    private List<File> files_sorted1;
    private List<File> files_sorted2;

    public MyFiles() {
        File f = new File("C:\\Users\\blablabla\\Desktop\\");
        files = new ArrayList<File>(Arrays.asList(f.listFiles()));
        for (Iterator<File> iter = files.iterator(); iter.hasNext();) {
            File file = iter.next();
            if (!file.isFile() || !file.canRead()) {
                iter.remove();
            }
        }
        Collections.shuffle(files); // TODO
        files_sorted1 = new ArrayList<File>(files);
        Collections.sort(files_sorted1);
        files_sorted2 = new ArrayList<File>(files);
        Collections.sort(files_sorted2, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                String n1 = o1.getName(), n2 = o2.getName();
                if (n1.length() < n2.length()) {
                    return 1;
                }
                if (n1.length() > n2.length()) {
                    return -1;
                }
                return n1.compareTo(n2);
            }
        });

        System.out.println(files); // TODO
        System.out.println(files_sorted1);
        System.out.println(files_sorted2);
    }

    public File getFile(int index, Boolean mode) {
        if (mode == null) {
            return files.get(index);
        }
        if (mode) {
            return files_sorted1.get(index);
        }
        return files_sorted2.get(index);
    }

    public String getFileName(int index, Boolean mode) {
        if (mode == null) {
            return files.get(index).getName();
        }
        if (mode) {
            return files_sorted1.get(index).getName();
        }
        return files_sorted2.get(index).getName();
    }

    public static void main(String[] args) {
        MyFiles mf = new MyFiles();
        for (int i = 0; i < 999; i++) { // TODO
            System.out.println(mf.getFileName(i, null));
            System.out.println(mf.getFileName(i, true));
            System.out.println(mf.getFileName(i, false));
            System.out.println("");
        }
    }
}```

Hab auch lange über eine Map nachgedacht, aber die macht in diesem Fall keinen sinn.

"TODO": An dieser Stelle kannst du werkeln oder weglassen.

Warum so kompliziert machen wenn es auch einfach geht :)?

An der Stelle möchte ich mal dezent auf den Link in meiner Signatur mit Namen „Naming Conventions“ hinweisen.

Richtig erkannt. Deswegen nochmal der wink: einfach das Array zu nehmen tuts in deinem Fall höchstwahrscheinlich auch. Zumindest solange es mithilfe von [japi]File#listFiles–[/japi] erstellt/befüllt wird.

Es ist nicht kompliziert, die Arbeit, shuffle (unnötig, nur Demo) und sort, macht Java schon, du musst nur die Methodenrückgabeergebnisliste in einer Objektvariablen zwischenspeichern, sonst ist das Proggi nicht effizient. Dafür kann man eine eigene Klasse nehmen, und dem Konstruktor z. B. den Verzeichnisnamen übergeben (da fehlt ein //TODO ). Anstatt dem Wrapper Boolean mode wäre auch boolean… denkbar, hier varArgs, oder ein zweiter Index. Bei mir ist die Liste schon nach der aktuellen/letzten Einstellung der Windows-Explorer-Darstellung sortiert. Objekte, die etwas speichern, das ist OOP, denke alles in Objekten. Oben fehlt die Klasse Item, ohne Item kann man Spekulation, was das Proggi machen soll. Viell. sagt Landei oder ein anderer auch noch was dazu.

*** Edit ***

Ich kenne die conventions. Aber wie würdest du Sortiertliste übersetzen (sortierte Liste)?, also so etwas wie Schnellauto (schnelles Auto)? So weit reichen meine Kenntnisse nicht. Also Englisch -5. :confused:

myObj
myVar
myVal
MY_CONST
myMethod
MyClazz
MyInterf
i
j
l
m
usw.

So ungefähr.

Es funktioniert doch alles perfekt :D? Wo gibts hier complains ?

public class Item
{

    private String name;
    private String quote; // Beschreibung
    private int cost;
    private int quantity; // Anzahl
    private int quality;

    public Item(String name,String quote, int cost , int quantity , int quality)
    {
        this.name = name;
        this.quote = quote;
        this.cost = cost;
        this.quantity = quantity;
        this.quality = quality;
    }

    public String getQuote()
    {
        return this.quote;
    }

    public int getQuality()
    {
        return this.quality;
    }	
    public int getQuantity()
    {
        return this.quantity;
    }

    public String getName()
    {
        return this.name;
    }

    public int getCost()
    {
        return cost;
    }
}