2009-11-01 20 views
25

Ich habe eine Datei in einen String gelesen. Die Datei enthält verschiedene Namen, einen Namen pro Zeile. Nun ist das Problem, dass ich diese Namen in einem String-Array möchte.Wie liest man eine Datei in eine Zeichenfolge in Java?

Dafür habe ich den folgenden Code geschrieben:

String [] names = fileString.split("\n"); // fileString is the string representation of the file 

Aber ich bin nicht immer die gewünschten Ergebnisse und die Anordnung erhalten wird, nachdem die Zeichenfolge Aufspalten der Länge 1. Es bedeutet, dass die „fileString“ doesn‘ t haben "\ n" Zeichen, aber die Datei hat dieses "\ n" Zeichen.

So, wie Sie dieses Problem umgehen?

+1

Warum wollen Sie die \ n zu halten. Kannst du nicht einfach davon ausgehen, dass es da ist? –

Antwort

28

Das Problem besteht nicht darin, wie Sie die Zeichenfolge aufteilen; dieses Bit ist korrekt.

Sie müssen überprüfen, wie Sie die Datei in die Zeichenfolge lesen. Sie brauchen etwas wie folgt aus:

private String readFileAsString(String filePath) throws IOException { 
     StringBuffer fileData = new StringBuffer(); 
     BufferedReader reader = new BufferedReader(
       new FileReader(filePath)); 
     char[] buf = new char[1024]; 
     int numRead=0; 
     while((numRead=reader.read(buf)) != -1){ 
      String readData = String.valueOf(buf, 0, numRead); 
      fileData.append(readData); 
     } 
     reader.close(); 
     return fileData.toString(); 
    } 
+7

Während ich richtig bin, habe ich ein Wort der Warnung für jeden, der dies sieht: Ich würde dieses genaue Code-Snippet nicht verwenden, da bei IOException der Reader niemals geschlossen wird und zu hängenden FileReadern führen kann, die niemals Müll gesammelt werden können. nix world bedeutet, dass Sie irgendwann keine Dateihandles mehr haben und Ihre JVM einfach abstürzt. – Esko

+4

Ein anderes Problem ist, dass "FileReader" implizit den Zeichensatz aufnimmt, der zufällig der Standard ist. Auch der Zwischenstring ist unnötig. –

8

Sie Ihre Datei in eine List anstelle eines String lesen konnte und dann in ein Array umwandeln:

//Setup a BufferedReader here  
List<String> list = new ArrayList<String>(); 
String line = reader.readLine(); 
while (line != null) { 
    list.add(line); 
    line = reader.readLine(); 
} 
String[] arr = list.toArray(new String[0]); 
+2

Oder lassen Sie es sogar als ein Array. –

+2

oder vielleicht lassen Sie die Datei allein – Blub

1

ich auf diese Weise immer wie folgt:

String content = ""; 
String line; 
BufferedReader reader = new BufferedReader(new FileReader(...)); 
while ((line = reader.readLine()) != null) 
{ 
    content += "\n" + line; 
} 
// Cut of the first newline; 
content = content.substring(1); 
// Close the reader 
reader.close(); 
+4

FYI: Lesen Sie normalerweise kleine Dateien mit diesem Code? Ich hätte mit dieser String-Verkettung eine signifikante Performance erwartet ... Ich will nicht negativ sein, ich bin nur neugierig. –

+0

Ehhm, ja ... Ist diese Methode veraltet? Oh, was bedeutet FYI? –

+1

FYI = For Your Information, eines der vielen gebräuchlichen Akronyme, die im Internet verwendet werden. – Esko

43

Wie wäre es mit Apache Commons (Commons IO und Commons Lang)?

+1

+1 - handelt eine Zeile Code für eine Abhängigkeit von Apache Commons IO und Lang. – duffymo

+2

Beachten Sie, dass dies jetzt FileUtils.readFileToString – pimlottc

5

Es gibt keine integrierte Methode in Java, die eine ganze Datei lesen kann. So haben Sie folgende Möglichkeiten:

  • eine Nicht-Standard-Bibliothek Methode verwenden, wie Apache Commons finden Sie im Codebeispiel in romaintaz Antwort.
  • Schleife um einige read Methode (z. B. FileInputStream.read, die Bytes liest, oder FileReader.read, die Zeichen liest; beide in ein zuvor zugeordnetes Array lesen). Beide Klassen verwenden Systemaufrufe, daher müssen Sie sie mit dem Buffering (BufferedInputStream oder BufferedReader) beschleunigen, wenn Sie nur eine kleine Datenmenge (z. B. weniger als 4096 Byte) gleichzeitig lesen.
  • Schleife um BufferedReader.readLine. Es gibt ein grundsätzliches Problem, dass es die Information verwirft, ob es am Ende der Datei einen '\n' gab - also z.B. Es ist nicht möglich, eine leere Datei von einer Datei zu unterscheiden, die nur einen Zeilenumbruch enthält.

    // charsetName can be null to use the default charset. 
    public static String readFileAsString(String fileName, String charsetName) 
        throws java.io.IOException { 
        java.io.InputStream is = new java.io.FileInputStream(fileName); 
        try { 
        final int bufsize = 4096; 
        int available = is.available(); 
        byte[] data = new byte[available < bufsize ? bufsize : available]; 
        int used = 0; 
        while (true) { 
         if (data.length - used < bufsize) { 
         byte[] newData = new byte[data.length << 1]; 
         System.arraycopy(data, 0, newData, 0, used); 
         data = newData; 
         } 
         int got = is.read(data, used, data.length - used); 
         if (got <= 0) break; 
         used += got; 
        } 
        return charsetName != null ? new String(data, 0, used, charsetName) 
               : new String(data, 0, used); 
        } finally { 
        is.close(); 
        } 
    } 
    

    Der obige Code hat folgende Vorteile:

    • Es ist richtig: es liest die gesamte Datei, keine Byte Verwerfen

    ich diesen Code verwenden würde.

  • Hier können Sie den Zeichensatz (Codierung) angeben, den die Datei verwendet.
  • Es ist schnell (egal wie viele Zeilenumbrüche die Datei enthält).
  • Es verschwendet keinen Speicher (egal wie viele Zeilenumbrüche die Datei enthält).
17

Wie Garrett Rowe and Stan James vorgeschlagen können Sie java.util.Scanner verwenden:

try (Scanner s = new Scanner(file).useDelimiter("\\Z")) { 
    String contents = s.next(); 
} 

oder

try (Scanner s = new Scanner(file).useDelimiter("\\n")) { 
    while(s.hasNext()) { 
    String line = s.next(); 
    } 
} 

Dieser Code hat keine externen Abhängigkeiten. Hier ist ein Beispiel dafür, wie java.util.Scanner mit dem richtigen Ressource zu verwenden und die Fehlerbehandlung:

import java.io.File; 
import java.io.FileNotFoundException; 
import java.util.Scanner; 
import java.util.Iterator; 

class TestScanner { 
    public static void main(String[] args) 
    throws FileNotFoundException { 
    File file = new File(args[0]); 

    System.out.println(getFileContents(file)); 

    processFileLines(file, new LineProcessor() { 
     @Override 
     public void process(int lineNumber, String lineContents) { 
     System.out.println(lineNumber + ": " + lineContents); 
     } 
    }); 
    } 

    static String getFileContents(File file) 
    throws FileNotFoundException { 
    try (Scanner s = new Scanner(file).useDelimiter("\\Z")) { 
     return s.next(); 
    } 
    } 

    static void processFileLines(File file, LineProcessor lineProcessor) 
    throws FileNotFoundException { 
    try (Scanner s = new Scanner(file).useDelimiter("\\n")) { 
     for (int lineNumber = 1; s.hasNext(); ++lineNumber) { 
     lineProcessor.process(lineNumber, s.next()); 
     } 
    } 
    } 

    static interface LineProcessor { 
    void process(int lineNumber, String lineContents); 
    } 
} 
+1

+1 für einfachste native Lösung ist. Übrigens, vergessen Sie nicht, Ressourcenlecks zu verhindern, indem Sie 'scanner.close();' – mmdemirbas

+1

@mmdemirbas verwenden, OK Ich habe ein vollständiges Beispiel mit Ressourcen- und Fehlerbehandlung hinzugefügt. Danke für die Warnung. –

3
FileReader fr=new FileReader(filename); 
BufferedReader br=new BufferedReader(fr); 
String strline; 
String arr[]=new String[10];//10 is the no. of strings 
while((strline=br.readLine())!=null) 
{ 
arr[i++]=strline; 
} 
1

Die einfachste Lösung für eine Textdatei Zeile für Zeile zu lesen und setzt die Ergebnisse in ein Array von Strings ohne Dritter mit

ArrayList<String> names = new ArrayList<String>(); 
Scanner scanner = new Scanner(new File("names.txt")); 
while(scanner.hasNextLine()) { 
    names.add(scanner.nextLine()); 
} 
scanner.close(); 
String[] namesArr = (String[]) names.toArray(); 
0

ein einfaches (ohne Schleifen), aber weniger korrekt Art und Weise, ist alles zu einem Byte-Array zu lesen: Bibliotheken wären dies

FileInputStream is = new FileInputStream(file); 
byte[] b = new byte[(int) file.length()]; 
is.read(b, 0, (int) file.length()); 
String contents = new String(b); 

Beachten Sie auch, dass dies schwerwiegende Leistungsprobleme hat.

0

Wenn Sie nur InputStream haben, können Sie InputStreamReader verwenden.

SmbFileInputStream in = new SmbFileInputStream("smb://host/dir/file.ext"); 
InputStreamReader r=new InputStreamReader(in); 
char buf[] = new char[5000]; 
int count=r.read(buf); 
String s=String.valueOf(buf, 0, count); 

Sie können bei Bedarf einen Zyklus und einen StringBuffer hinzufügen.

0

Sie können auch java.nio.file.Files verwenden eine ganze Datei in eine String-Liste zu lesen, dann können Sie es in ein Array umwandeln usw. Unter der Annahme eines String-Variable namens filePath die folgenden 2 Zeilen tun, dass:

List<String> strList = Files.readAllLines(Paths.get(filePath), Charset.defaultCharset()); 
String[] strarray = strList.toArray(new String[0]); 
4

Besonders ich liebe dieses mit dem java.nio.file Paket auch beschrieben here.

String content = new String(Files.readAllBytes(Paths.get("/path/to/file"))); 

Cool huhhh!

0

Sie können Cactoos versuchen:

import org.cactoos.io.TextOf; 
import java.io.File; 
new TextOf(new File("a.txt")).asString().split("\n") 
Verwandte Themen