[英]How do I read only the last line of a csv file in Java?
我有一個 csv 文件,它的行數並不總是相同。 但是,我想要一種只讀取最后一行的方法,這樣我就可以訪問最后一行的第一列。 到目前為止,我還沒有找到解決方案,正是這樣做的。
現在我正處於我會用 BufferedReader 讀取每一行並將其保存到數組中的點上。
public void readPreviousEntryID(){
String path = "csvs/cartEntries.csv";
try {
BufferedReader br = new BufferedReader((new FileReader(path)));
String line;
while ((line = br.readLine() != null)) {
String[] values = line.split(",");
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
通常我會使用 values[0] 訪問每一行的第一個條目。 但我只想要最后一行的第一個值。
我想過通過增加 integer 然后使用 integer 的最終值來訪問相應的行來計算 while 循環中的行數,但我不確定這是否可行或我將如何實現它。
我希望我包含了足夠的信息以使問題易於理解。 這是我在這里的第一個問題,我對 Java 很陌生。
只需循環讀取文件的行並保存讀取的最后一行的values
。 循環終止后, values
包含文件中最后一行的內容。
public void readPreviousEntryID() throws IOException {
String path = "csvs/cartEntries.csv";
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
String[] values = null;
String line = br.readLine();
while (line != null) {
values = line.split(",");
line = br.readLine();
}
if (values == null) {
throw new IOException("File is empty.");
}
// Handle 'values[0]'
}
}
上述代碼的優點是不需要將整個文件內容存儲在計算機 memory 中。 如果 CSV 文件非常大,您可能會得到OutOfMemoryError 。
請注意,在閱讀完文件后關閉文件很重要。 從 Java 7 開始,您可以使用try-with-resources 。
與其捕獲IOException
並將其包裝在RuntimeException
中,我建議您簡單地聲明方法readPreviousEntryID
可能會拋出IOException
。 請參閱未經檢查的異常 - 爭議。
在循環終止后檢查values
是否包含預期的元素數量可能也是一個好主意,例如
if (values.length == 5) {
// Handle 'values[0]'
}
else {
throw new IOException("Invalid last line.");
}
或者,無需拆分每一行。 只需保存最后一行讀取並在循環終止后拆分最后一行。
public void readPreviousEntryID() throws IOException {
String path = "csvs/cartEntries.csv";
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
String lastLine = null;
String line = br.readLine();
while (line != null) {
lastLine = line;
line = br.readLine();
}
if (lastLine == null) {
throw new IOException("File is empty.");
}
String[] values = lastLine.split(",");
// Handle 'values[0]'
}
}
為什么不將所有行存儲到 List 並獲取最后一行詳細信息,如下所示
private List<String[]> readLines = new ArrayList<>();
public void readPreviousEntryID(){
String path = "csvs/cartEntries.csv";
try {
String line;
BufferedReader br = new BufferedReader(new FileReader(path));
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
readLines.add(values);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String[] getLastLine() {
return readLines.get(readLines.size()-1);
}
上面的 function 將給出 csv 文件的最后一行。
在 Linux 中,可以使用tail
命令打印最后n行。 搜索java tail
會得到一些實現。
大文件的一個很好的快速實現將使用 RandomAccessFile,可能是 MemoryMappedByteBuffer,然后從末尾搜索\n
。
在您的情況下,您可以保持簡單。
public String readPreviousEntryID(){
Path path = Paths.get("csvs/cartEntries.csv");
try (Stream<String> lines = Files.lines(path, Charset.defaultCharset())) {
return lines
.filter(line -> !line.isEmpty())
.reduce("", (acc, line) -> line);
} catch (FileNotFoundException e) {
// You gave a relative path, show the actual full path:
System.out.println("File not found: " + Files.toAbsolutePath());
throw new RuntimeException(e);
} // Automatically closes the Stream lines, even on exception or return.
}
try (... declarations of AutoCloseables...) {... }
確保調用.close()
。x ->...
或(x, y) ->...
分別聲明一個匿名 function 。 2個參數聲明。File
的概括。 路徑也可以來自 URL、zip 文件等。Path
相關的好東西。 Files
.已經發布了一些好的答案。 這是使用流的變體。
此外,了解 NIO.2 作為使用 Java 中文件的現代方式。
一些未經測試的代碼嘗試:
Path path = Paths.get( "/csvs" , "cartEntries.csv" ) ;
Optional < String > lastLine =
Files
.lines( path )
.reduce( ( previousLine , currentLine ) -> currentLine ) ;
if( lastLine.isPresent() ) {
String[] parts = lastLine.get().split( "," ) ;
…
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.