[英]How do I read only the last line of a csv file in Java?
I have a csv file that doesn't always have the same number of lines.我有一个 csv 文件,它的行数并不总是相同。 However, I want a method to only read me the last line, so I can access the first column of that last line.
但是,我想要一种只读取最后一行的方法,这样我就可以访问最后一行的第一列。 So far I haven't found a solution, that does exactly that.
到目前为止,我还没有找到解决方案,正是这样做的。
Right now I'm just at the point were I would read every single line with BufferedReader and save it into an Array.现在我正处于我会用 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);
}
}
Normally I would then access the first entry of every line by using values[0].通常我会使用 values[0] 访问每一行的第一个条目。 But I just want the first value of the last line.
但我只想要最后一行的第一个值。
I thought about counting the number of lines in the while loop by incrementing an integer and then using the final value of that integer to access the corresponding line, but I'm not sure if this would work or how I would implement that.我想过通过增加 integer 然后使用 integer 的最终值来访问相应的行来计算 while 循环中的行数,但我不确定这是否可行或我将如何实现它。
I hope I included enough information to make the problem understandable.我希望我包含了足够的信息以使问题易于理解。 This is my first question here and I'm quite new to Java.
这是我在这里的第一个问题,我对 Java 很陌生。
Simply read the lines of the file in a loop and save the values
of the last line read.只需循环读取文件的行并保存读取的最后一行的
values
。 After the loop terminates, values
contains the contents of the last line in the file.循环终止后,
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]'
}
}
The advantage of the above code is that you don't need to store the entire file contents in the computer memory.上述代码的优点是不需要将整个文件内容存储在计算机 memory 中。 If the CSV file is very large, you may get OutOfMemoryError .
如果 CSV 文件非常大,您可能会得到OutOfMemoryError 。
Note that is important to close a file after you have finished reading it.请注意,在阅读完文件后关闭文件很重要。 Since Java 7 you can use try-with-resources .
从 Java 7 开始,您可以使用try-with-resources 。
Rather than catch the IOException
and wrap it in a RuntimeException
, I suggest that you simply declare that method readPreviousEntryID
may throw an IOException
.与其捕获
IOException
并将其包装在RuntimeException
中,我建议您简单地声明方法readPreviousEntryID
可能会抛出IOException
。 Refer to Unchecked Exceptions — The Controversy .请参阅未经检查的异常 - 争议。
It is probably also a good idea to check, after the loop terminates, that values
contains the expected number of elements, eg在循环终止后检查
values
是否包含预期的元素数量可能也是一个好主意,例如
if (values.length == 5) {
// Handle 'values[0]'
}
else {
throw new IOException("Invalid last line.");
}
Alternatively, no need to split every line.或者,无需拆分每一行。 Just save the last line read and split that last line after the loop terminates.
只需保存最后一行读取并在循环终止后拆分最后一行。
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]'
}
}
Why not stored all lines into List and get last line details such as follows为什么不将所有行存储到 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);
}
This above function will gives the last row of csv file.上面的 function 将给出 csv 文件的最后一行。
In Linux one would use the tail
command to print the n last lines.在 Linux 中,可以使用
tail
命令打印最后n行。 Search java tail
will get you some implementations.搜索
java tail
会得到一些实现。
A good fast implementation for large files would use a RandomAccessFile, maybe a MemoryMappedByteBuffer, and search back from the end for a \n
.大文件的一个很好的快速实现将使用 RandomAccessFile,可能是 MemoryMappedByteBuffer,然后从末尾搜索
\n
。
In your case you can keep it simple.在您的情况下,您可以保持简单。
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...) {... }
ensuring the call to .close()
. try (... declarations of AutoCloseables...) {... }
确保调用.close()
。x ->...
or (x, y) ->...
declare an anonymous function with 1 resp. x ->...
或(x, y) ->...
分别声明一个匿名 function 。 2 parameter declarations. File
. File
的概括。 Path can also be from an URL, inside a zip file etcetera.Path
related goodies. Path
相关的好东西。 Files
. Files
. Some good Answers have been posted.已经发布了一些好的答案。 Here is a variation using streams.
这是使用流的变体。
Also, learn about NIO.2 as the modern way to work with files in Java.此外,了解 NIO.2 作为使用 Java 中文件的现代方式。
Some untested code to try:一些未经测试的代码尝试:
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.