Eine Zeile aus einer Textdatei lesen und deren Inhalt aufteilen

138518
KyelJmD

Ich habe diese Art von Dateistruktur

MALE:FooBar:32
FEMALE:BarFoo:23

Wo ich das Geschlecht und das Alter der Person ermitteln möchte, <Gender>:<Name>:<age>

try{
    BufferedReader in = new BufferedReader(new FileReader("people.ser"));
    String s;

    while((s = in.readLine()) != null){

        String[] var = s.split(":");
             //var[0]=MALE etc etc
        addGender.add(var[0]);
    }

}catch(Exception e){
    e.printStackTrace();
}
  • Ist die Verwendung eines Trennzeichens (wie :in diesem Fall eines) zum Unterteilen von Zeichenketten eine schlechte Praxis?
  • Wie wäre es mit dem Array aus der geteilten Zeichenfolge, um es an einem bestimmten Ort zu speichern?
  • Gibt es Alternativen und eine bessere Dateistruktur?
Antworten
5
String.split (RegEx) wird jetzt für neue Java-Versionen empfohlen (StringTokenizer für Kompatibilität mit älteren Versionen). Mit "palacsint" -Anweisungen sehen Sie einen guten Code aus. cl-r vor 8 Jahren 0

2 Antworten auf die Frage

8
palacsint

Ich denke nicht, dass das Verwenden :eine schlechte Praxis ist, aber Sie müssen es irgendwie umgehen, wenn es in Ihren Daten vorkommt. Jedenfalls würde ich erwägen, XML oder JSON hier zu verwenden.

Einige Anmerkungen zum Code:

  1. Sie sollten den Stream (in einem finallyBlock) schließen. Siehe Leitlinie 1-2: Veröffentlichung Ressourcen in allen Fällen in sicheren Coding Richtlinien für die Programmiersprache Java
  2. Die .serDateierweiterung wird häufig für serialisierte Java-Objekte verwendet. Ich würde etwas anderes verwenden, um mögliche Verwirrung zu vermeiden.
  3. Es empfiehlt sich, den Zeichensatz festzulegen, wenn Sie eine Textdatei lesen. Die verwendeten verwenden FileReaderimmer den Standardzeichensatz, der von System zu System variieren kann. Erwägen Sie die Verwendung InputStreamReaderund FileInputStreamwie die Dokumentation FileReadersagt . Hier ist ein Beispiel:

    FileInputStream fileInputStream = null;
    InputStreamReader inputStreamReader = null;
    BufferedReader bufferedReader = null;
    try {
        fileInputStream = new FileInputStream("people.dat");
        inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
        bufferedReader = new BufferedReader(inputStreamReader);
    
        // use BufferedReader here
    } finally {
        IOUtils.closeQuietly(bufferedReader);
        IOUtils.closeQuietly(inputStreamReader);
        IOUtils.closeQuietly(fileInputStream);
    }
    

    Es wird IOUtilsvon Apache Commons IO verwendet und schließt FileInputStreamselbst dann, wenn der Konstruktor InputStreamReaderoder BufferedReadereine Ausnahme auslöst.

Wie würde ich Nummer 3 machen? KyelJmD vor 8 Jahren 0
@KyelJmD: Bitte sehen Sie sich die Bearbeitung an. palacsint vor 8 Jahren 0
warum hast du final verwendet? KyelJmD vor 8 Jahren 0
@KyelJmD: `final` hilft Lesern und Betreuern, da sie wissen, dass die Referenz immer auf dieselbe Instanz verweist und sich später nicht ändert. http://programmers.stackexchange.com/questions/115690/why-declare-final-variables-inside-methods. Sie können jedoch auch andere Fragen zu Programmers.SE im Thema finden. palacsint vor 8 Jahren 0
Ich würde diese letzten Variablen in der Klasse platzieren? oder in einer Methode, die sie aufruft? KyelJmD vor 8 Jahren 0
@KyelJmD: Ich habe ein detaillierteres Beispiel hinzugefügt. palacsint vor 8 Jahren 0
4
poorman

Scanner ist etwas einfacher zu benutzen als BufferedReader ...

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class Main {

    public static void main(String[] args) {        
        try {
            File f = new File("people.ser");
            Scanner sc = new Scanner(f);

            List<Person> people = new ArrayList<Person>();

            while(sc.hasNextLine()){
                String line = sc.nextLine();
                String[] details = line.split(":");
                String gender = details[0];
                String name = details[1];
                int age = Integer.parseInt(details[2]);
                Person p = new Person(gender, name, age);
                people.add(p);
            }

            for(Person p: people){
                System.out.println(p.toString());
            }

        } catch (FileNotFoundException e) {         
            e.printStackTrace();
        }
    }
}

class Person{

    private String gender;
    private String name;
    private int age;

    public Person(String gender, String name, int age){
        this.gender = gender;
        this.setName(name);
        this.age = age;
    }

    /**
     * @return the gender
     */
public String getGender() {
    return gender;
}

/**
 * @param gender the gender to set
 */
public void setGender(String gender) {
    this.gender = gender;
}

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @return the name
 */
public String getName() {
    return name;
}

/**
 * @return the age
 */
public int getAge() {
    return age;
}

/**
 * @param age the age to set
 */
public void setAge(int age) {
    this.age = age;
}

public String toString(){
    return this.gender + " " + this.name + " " + this.age;
}


}
Die toString () -Methode sollte anstelle der Verkettung `StringBuilder` verwenden. Eva vor 7 Jahren 0
Da die toString () -Methode wahrscheinlich nur für Debugging-Zwecke verwendet wird, würde ich sagen, dass Lesbarkeit hier die Leistung übertrumpft und die aktuelle Implementierung viel lesbarer ist. Falls es bei starker Iteration verwendet wird, könnte dies ein anderer Fall sein. Nihathrael vor 5 Jahren 0