在java读字符串入文件_如何在java中将文件读入字符串?
我已經將文件讀入String。 該文件包含各種名稱,每行一個名稱。 現在的問題是我想在String數組中使用這些名稱。
為此我寫了以下代碼:
String [] names = fileString.split("
"); // fileString is the string representation of the file
但是我沒有得到所需的結果,并且在分割字符串后獲得的數組長度為1.這意味著"fileString"沒有" n"字符,但文件中有" n"字符。
那么如何解決這個問題呢?
為什么要保留 n。 你能不能假設它在那里?
那么使用Apache Commons(Commons IO和Commons Lang)呢?
String[] lines = StringUtils.split(FileUtils.readFileToString(new File("...")), '
');
+1 - 交換一行代碼以依賴Apache Commons IO和Lang。
請注意,現在這是FileUtils.readFileToString
問題不在于你如何拆分字符串;那個位是正確的。
您必須查看如何將文件讀取到字符串。你需要這樣的東西:
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();
}
雖然正確我對任何看到這個的人都有一個警告:我不會使用這個確切的代碼片段,因為如果拋出IOException,讀者永遠不會關閉并且可能導致掛起的文件讀取器永遠不會被垃圾收集在* nix中world意味著你最終會耗盡文件句柄,你的JVM就會崩潰。
另一個問題是FileReader隱含地接收了默認情況下的任何字符集。中間String也是不必要的。
StringBuilder可能是比StringBuffer更好的選擇。從StringBuffer javadoc開始:"從發布JDK 5開始,這個類已經補充了一個設計用于單個線程StringBuilder的等效類。通常應優先使用StringBuilder類,因為它支持所有相同的操作但它更快,因為沒有同步。"
根據Garrett Rowe和Stan James的建議,您可以使用java.util.Scanner:
try (Scanner s = new Scanner(file).useDelimiter("\\Z")) {
String contents = s.next();
}
要么
try (Scanner s = new Scanner(file).useDelimiter("\
")) {
while(s.hasNext()) {
String line = s.next();
}
}
此代碼沒有外部依賴項。
警告:您應該將charset編碼指定為Scanner構造函數的第二個參數。在這個例子中,我使用的是平臺的默認值,但這肯定是錯誤的。
以下是如何使用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("\
")) {
for (int lineNumber = 1; s.hasNext(); ++lineNumber) {
lineProcessor.process(lineNumber, s.next());
}
}
}
static interface LineProcessor {
void process(int lineNumber, String lineContents);
}
}
+1用于最簡單的原生解決方案。順便說一句,不要忘記使用scanner.close();防止資源泄漏
@mmdemirbas,好的我已經添加了一個包含資源和錯誤處理的完整示例。謝謝你的提醒。
當讀取與預期編碼不同的編碼時,掃描程序有一個令人討厭的錯誤,請參閱:stackoverflow.com/questions/8330695/
@golimar,錯誤在我自己的代碼中:我應該將charset指定為Scanner構造函數的第二個參數,而不是依賴于默認的charset。
@MarcelloNuccio不,問題是當Scanner找到的編碼與指定的編碼不同(或默認編碼)時,它會退出返回部分字符串(具有隨機大小)并且不會給出任何錯誤或警告消息
@golimar同意:Scanner中的錯誤報告是錯誤的。但是使用錯誤的編碼來讀取文件是我自己的代碼中的一個錯誤。如何在不知道字符編碼的情況下閱讀一些文字?
@MarcelloNuccio True。但是,有時您需要的文件的唯一部分是ascii-only(例如,帶有ascii-only命令的shell腳本和將被丟棄的非ascii注釋)
請參閱我對stackoverflow.com/a/52971742/453605的評論
特別是我喜歡這個使用此處描述的java.nio.file包。
String content = new String(Files.readAllBytes(Paths.get("/path/to/file")));
很酷啊!
這可能是最好的答案!!
您可以將文件讀入List而不是String,然后轉換為數組:
//Setup a BufferedReader here
List list = new ArrayList();
String line = reader.readLine();
while (line != null) {
list.add(line);
line = reader.readLine();
}
String[] arr = list.toArray(new String[0]);
或者甚至把它留作陣列。
或者可以完全保留文件
Java中沒有可以讀取整個文件的內置方法。所以你有以下選擇:
使用非標準的庫方法,例如Apache Commons,請參閱romaintaz的答案中的代碼示例。
循環一些read方法(例如FileInputStream.read,讀取字節,或FileReader.read,讀取字符;兩者都讀取到預分配的數組)。這兩個類都使用系統調用,因此如果您一次只讀取少量數據(例如,小于4096字節),則必須通過緩沖(BufferedInputStream或BufferedReader)來加速它們。
環繞BufferedReader.readLine。存在一個基本問題,它丟棄信息是否在文件的末尾有'
' - 例如,它無法區分空文件和僅包含換行符的文件。
我用這個代碼:
// 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();
}
}
上面的代碼具有以下優點:
這是正確的:它讀取整個文件,而不是丟棄任何字節。
它允許您指定文件使用的字符集(編碼)。
它很快(無論文件包含多少個換行符)。
它不會浪費內存(無論文件包含多少個換行符)。
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;
}
逐行讀取文本文件并將結果放入字符串數組而不使用第三方庫的最簡單的解決方案是:
ArrayList names = new ArrayList();
Scanner scanner = new Scanner(new File("names.txt"));
while(scanner.hasNextLine()) {
names.add(scanner.nextLine());
}
scanner.close();
String[] namesArr = (String[]) names.toArray();
我一直用這種方式:
String content ="";
String line;
BufferedReader reader = new BufferedReader(new FileReader(...));
while ((line = reader.readLine()) != null)
{
content +="
" + line;
}
// Cut of the first newline;
content = content.substring(1);
// Close the reader
reader.close();
僅供參考:你經常閱讀帶有該代碼的小文件嗎?我本來期望在所有String連接中出現重大的性能損失......我不是故意要消極,我只是好奇。
嗯,是的......這種方法是否被棄用了?哦,FYI是什么意思?
FYI = For Your Information,是Web上使用的眾多常見縮寫詞之一。
為什么要收集字符串而不是每行一個字符串列表?您通常需要事后對收集的數據執行某些操作。
我想Adam指出的問題是你在循環中進行字符串連接+ =,這意味著你每次都創建一個新的String對象(因為字符串是不可變的)。這對性能產生了相當大的負面影響。使用StringBuilder(并執行append())而不是內容的字符串。
謝謝你的提示。我將在未來中使用這種方式。現在終于我得到了一個關于+ = operater和新實例的anwser。謝謝
你可以試試Cactoos:
import org.cactoos.io.TextOf;
import java.io.File;
new TextOf(new File("a.txt")).asString().split("
")
您還可以使用java.nio.file.Files將整個文件讀入字符串列表,然后將其轉換為數組等。假設一個名為filePath的String變量,以下兩行將執行此操作:
List strList = Files.readAllLines(Paths.get(filePath), Charset.defaultCharset());
String[] strarray = strList.toArray(new String[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);
如果需要,您可以添加cycle和StringBuffer。
更簡單(沒有循環)但不太正確的方法是將所有內容讀取到字節數組:
FileInputStream is = new FileInputStream(file);
byte[] b = new byte[(int) file.length()];
is.read(b, 0, (int) file.length());
String contents = new String(b);
另請注意,這有嚴重的性能問題。
總結
以上是生活随笔為你收集整理的在java读字符串入文件_如何在java中将文件读入字符串?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吸粪车多少钱啊?
- 下一篇: java向某一IP发送消息_javaTC