2009-11-01 29 views
25

我已經將文件讀入字符串。該文件包含各種名稱,每行一個名稱。現在問題是我想要一個字符串數組中的這些名稱。如何在java中將文件讀入字符串?

對於我寫以下代碼:

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

但是我沒有得到所期望的結果和分割後的字符串中得到的數組是長度爲1的這意味着,「fileString」沒有按」沒有「\ n」字符,但文件有這個「\ n」字符。

那麼如何解決這個問題?

+1

你爲什麼要保留\ n。你不能假設它在那裏嗎? –

回答

28

問題不在於如何拆分字符串;那一點是正確的。

您必須檢查如何將文件讀取到字符串。你需要的東西是這樣的:

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

雖然正確,但對於看到此消息的任何人我都有一個警告:我不會使用此確切的代碼片斷,因爲如果引發IOException,讀取器永遠不會關閉,並且可能導致掛起的FileReader永遠不會被垃圾收集, nix世界意味着你最終將耗盡文件句柄,而你的JVM只是簡單地崩潰。 – Esko

+4

另一個問題是'FileReader'隱含地拾取了恰好是默認的字符集。中間的'String'也是不必要的。 –

8

你能讀懂你的文件轉換成List而不是String,然後轉換爲數組:

//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

甚至把它作爲一個數組。 –

+2

或者可能將文件全部保留在一起 – Blub

1

我總是用這樣的方式:

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

供參考:您是否通常使用該代碼讀取小文件?我希望所有這些字符串連接都會帶來顯着的性能提升......我並不是說要消極,我只是好奇而已。 –

+0

Ehmm,是...這種方法是否被棄用?哦,FYI是什麼意思? –

+1

供參考=爲您的信息,網上使用的許多常見縮寫之一。 – Esko

43

如何使用Apache CommonsCommons IOCommons Lang)?

String[] lines = StringUtils.split(FileUtils.readFileToString(new File("...")), '\n'); 
+1

+1 - 爲Apache Commons IO和Lang的依賴交易一行代碼。 – duffymo

+2

請注意,現在這是FileUtils.readFileToString – pimlottc

5

Java中沒有可以讀取整個文件的內置方法。因此,您有以下選擇:

  • 使用非標準庫方法,例如Apache Commons,請參閱romaintaz答案中的代碼示例。
  • 圍繞一些read方法(例如,讀取字節的FileInputStream.read或讀取字符的FileReader.read)讀取到預分配的數組。這兩個類都使用系統調用,所以如果您一次只讀取少量數據(比如說,小於4096字節),則必須使用緩衝來加速(BufferedInputStreamBufferedReader)。
  • 環繞BufferedReader.readLine。存在根本性問題,即它丟棄了文件末尾是否有'\n'的信息 - 例如,它無法區分僅包含換行符的文件中的空文件。

我會使用此代碼:

// 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(); 
    } 
} 

上面的代碼具有以下優點:

  • 這是正確的:它讀取整個文件,而不是丟棄任何字節。
  • 它允許您指定文件使用的字符集(編碼)。
  • 速度很快(不管文件包含多少換行符)。
  • 它不浪費內存(不管文件包含多少換行符)。
17

正如Garrett Rowe and Stan James建議您可以使用java.util.Scanner

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

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

此代碼不存在外部依賴性。下面是如何使用java.util.Scanner與正確的資源和錯誤處理的例子:

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的最簡單的本機解決方案。順便說一下,不要忘記使用'scanner.close();' – mmdemirbas

+1

@mmdemirbas來防止資源泄漏,我已經添加了一個完整的資源和錯誤處理示例。謝謝你的提醒。 –

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

爲逐行讀取文本文件中的行,並把結果放到一個字符串數組,而無需使用第三方最簡單的解決方案圖書館會是這樣:

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

更簡單(沒有循環),但不正確的方式,是閱讀一切的字節數組:

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

另請注意,這存在嚴重的性能問題。

0

如果您只有InputStream,則可以使用InputStreamReader。

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); 

如果需要,您可以添加循環和StringBuffer。

0

您還可以使用java.nio.file.Files到整個文件讀入一個字符串列表,那麼你可以將其轉換爲一個數組等假定命名文件路徑,下面兩行會做一個字符串變量:

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

特別是我喜歡這個使用java.nio.file包也描述here

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

很酷的呵呵!

0

您可以嘗試Cactoos

import org.cactoos.io.TextOf; 
import java.io.File; 
new TextOf(new File("a.txt")).asString().split("\n") 
相關問題