在Java中如何以相反的顺序逐行读取文件 - 完整教程
已发表: 2013-03-30这是一个使用 Java8 API 以相反顺序逐行读取文件的最简单 Java 程序。 试试看,如果您发现任何问题,请告诉我。
- 用于反转文件内容的java程序
- 编写一个程序,用它的反向替换文件的每一行
我将编写 Java 面试系列,您将在其中找到更多相关的问题和答案。 请继续关注以获取更多信息。
在本教程中,我们将介绍以下步骤:
- 我们将读取位于 Document 位置的文件
crunchify.txt
。 我使用的是 Macbook pro,所以如果您使用不同的操作系统和笔记本电脑/台式机,请在程序CrunchifyReverseLineReader.java
中相应地更改文件路径 - 我们将首先以简单顺序读取文件。
- 然后我们将以相反的顺序读取文件。
-
Please note
:默认情况下,以下程序会从反向输出中删除所有空行。 如果您想保留空白行,请查看程序本身的注释。 - 创建文件
CrunchifyReverseLineReaderTest.java
并将下面的代码复制到测试结果。
Java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
package crunchify . com . tutorials ; import java . io . ByteArrayOutputStream ; import java . io . File ; import java . io . IOException ; import java . io . RandomAccessFile ; import java . io . UnsupportedEncodingException ; import java . nio . ByteBuffer ; import java . nio . channels . FileChannel ; /** * Read a file from end to start * * @author Crunchify.com */ public class CrunchifyReverseLineReader { private static final int BUFFER_SIZE = 8192 ; private final FileChannel channel ; private final String encoding ; private long filePos ; private ByteBuffer buf ; private int bufPos ; private ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ; private RandomAccessFile raf ; private byte lastLineBreak = '\n' ; public CrunchifyReverseLineReader ( File file ) throws IOException { this ( file , null ) ; } public CrunchifyReverseLineReader ( File file , String encoding ) throws IOException { raf = new RandomAccessFile ( file , "r" ) ; channel = raf . getChannel ( ) ; filePos = raf . length ( ) ; this . encoding = encoding ; } public void close ( ) throws IOException { raf . close ( ) ; } public String readLine ( ) throws IOException { byte c ; while ( true ) { if ( bufPos < 0 ) { if ( filePos == 0 ) { if ( baos == null ) { return null ; } String line = bufToString ( ) ; baos = null ; return line ; } long start = Math . max ( filePos - BUFFER_SIZE , 0 ) ; long end = filePos ; long len = end - start ; buf = channel . map ( FileChannel . MapMode . READ_ONLY , start , len ) ; bufPos = ( int ) len ; filePos = start ; // Ignore Empty New Lines c = buf . get ( -- bufPos ) ; if ( c == '\r' | | c == '\n' ) while ( bufPos > 0 && (c == '\r' || c == '\n')) { bufPos--; c = buf . get ( bufPos ) ; } if ( ! ( c == '\r' | | c == '\n' ) ) bufPos ++ ; // IS THE NEW LENE } /* * This will ignore all blank new lines. */ while ( bufPos -- > 0 ) { c = buf . get ( bufPos ) ; if ( c == '\r' | | c == '\n' ) { // skip \r\n while ( bufPos > 0 && (c == '\r' || c == '\n')) { c = buf.get(--bufPos); } // restore cursor if ( ! ( c == '\r' | | c == '\n' ) ) bufPos ++ ; // IS THE NEW Line return bufToString ( ) ; } baos . write ( c ) ; } /* * If you don't want to ignore new line and would like * to print new line too then use below code * and comment out above while loop while (bufPos-- > 0) { byte c1 = buf.get(bufPos); if (c1 == '\r' || c1 == '\n') { if (c1 != lastLineBreak) { lastLineBreak = c1; continue; } lastLineBreak = c1; return bufToString(); } baos.write(c1); } */ } } private String bufToString ( ) throws UnsupportedEncodingException { if ( baos . size ( ) == 0 ) { return "" ; } byte [ ] bytes = baos . toByteArray ( ) ; for ( int i = 0 ; i < bytes . length / 2 ; i ++ ) { byte t = bytes [ i ] ; bytes [ i ] = bytes [ bytes . length - i - 1 ] ; bytes [ bytes . length - i - 1 ] = t ; } baos . reset ( ) ; if ( encoding ! = null ) return new String ( bytes , encoding ) ; else return new String ( bytes ) ; } } |
根据 francesco 的评论,更新了代码以从文件中删除空白行。

其他必读文章:https://crunchify.com/why-and-for-what-should-i-use-enum-java-enum-examples/
现在让我们测试一下。 创建测试文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package crunchify . com . tutorials ; import java . io . BufferedReader ; import java . io . File ; import java . io . FileReader ; import java . io . IOException ; /** * @author Crunchify.com */ public class CrunchifyReverseLineReaderTest { @SuppressWarnings ( "resource" ) public static void main ( String [ ] args ) throws IOException { /* * If you want to have blank file and would like to add some lines then use below code * * File file = new File("/Users/appshah/Documents/crunchify.txt"); RandomAccessFile raf = new RandomAccessFile(file, * "rw"); for (int i = 0; i <= 10; i++) { // Adding line from 1 to 10 //raf.writeBytes("Adding Line " + i + "\n"); } * raf.close(); * */ /* * Test - 1: In this tutorial we will read exsiting file crunchify.txt * Reading file in Simple Order */ FileReader logReader = new FileReader ( "/Users/appshah/Documents/crunchify.txt" ) ; BufferedReader buffer = new BufferedReader ( logReader ) ; System . out . println ( "~~~~~~~~~~~~~~~~~~~Simple way to read file in Java without Reversing ~~~~~~~~~~~~~~~~~~\n" ) ; for ( String line1 = buffer . readLine ( ) ; line1 ! = null ; line1 = buffer . readLine ( ) ) { System . out . println ( line1 ) ; } /* * Test - 2: In this tutorial we will read exsiting file crunchify.txt * Reading file in Reverse Order */ File file = new File ( "/Users/appshah/Documents/crunchify.txt" ) ; CrunchifyReverseLineReader reader = new CrunchifyReverseLineReader ( file , "UTF-8" ) ; String line ; System . out . print ( "\n~~~~~~~~~~~~~~~~~~~ Reading a file in Reverse Order ~~~~~~~~~~~~~~~~~~~ \n\n" ) ; while ( ( line = reader . readLine ( ) ) ! = null ) { System . out . println ( line ) ; } } } |
Note:
文件 crunchify.txttotal 11 lines
,包括中间的 1 个空白行,如下面的结果所示。
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Simple way to read file in Java without Reversing ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ —————— Crunchify Tutorials Start —————— How To Troubleshoot Higher CPU , Memory & Process Usage ? Top 7 Tips To Speed Up WordPress & Boost Performance Detailed Guide On How To Install SSL On WordPress Site List Of All Genesis WordPress Framework Tips Simplest Hello World Spring MVC Tutorial And JDBC MySQL Tutorial NEW Start Embedded HTTP Jersey Server During Java Application Startup NEWTop 10 Java Interview Questions Answers Java Properties File : How To Read Config . Properties Values In Java ? —————— Crunchify Tutorials End —————— ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Reading a file in Reverse Order ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ —————— Crunchify Tutorials End —————— Java Properties File : How To Read Config . Properties Values In Java ? NEWTop 10 Java Interview Questions Answers NEW Start Embedded HTTP Jersey Server During Java Application Startup Simplest Hello World Spring MVC Tutorial And JDBC MySQL Tutorial List Of All Genesis WordPress Framework Tips Detailed Guide On How To Install SSL On WordPress Site Top 7 Tips To Speed Up WordPress & Boost Performance How To Troubleshoot Higher CPU , Memory & Process Usage ? —————— Crunchify Tutorials Start —————— |