1

How to read a file only 5 line and line in sort to descending. Example I have a file my.log with the following contents:

one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve

And i want the result is as follows:

twelve
eleven
ten
nine
eight

My code now is :

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class MainActivity extends Activity {

    long sleepTime = 1000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String log = "/sdcard/my.log";
        try {
            Tail(log);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void Tail(String filename) throws IOException {
        File checkfile = new File(filename);
        if (checkfile.exists()) {
            BufferedReader input = new BufferedReader(new FileReader(filename));
            String currentLine = null;

            while (true) {
                if ((currentLine = input.readLine()) != null) {
                    Log.d("MyLog", currentLine);
                    continue;
                }

                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }

            }
            input.close();
        } else {
            Log.d("MyLog", "File not found...");
        }
    }

}

But this time the result is all the content in the file in print and result not sort by descending. So now the result is as below:

one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve

Thanks.

Dave Jackson
  • 837
  • 5
  • 19
  • 28

7 Answers7

2

You need to cache all lines in a List first. Then you can get the five last lines.

List<String> l = new List<String>();
...
l.add(currentLine);
...
for(int i = 0; i < 5; i++){
    Log.d("MyLog", l.get(l.size() - i - 1));
}
SimonSays
  • 10,867
  • 7
  • 44
  • 59
1

Maintain an array of 5 strings and populate with file lines circularly. Then just enumerate in reverse order:

int MAX_LINES_COUNT = 5;
String[] lastFiveLines = new String[MAX_LINES_COUNT];    
int lineNumber = 0;

// populate
// .... inside the loop

         lastFiveLines[lineNumber++ % MAX_LINES_COUNT] = currentLine;

//....
// Now get the last five lines

for(int i=0; i<MAX_LINES_COUNT; i++)
{
    Log.d("MyLog", lastFiveLines[(--lineNumber) % MAX_LINES_COUNT]);
}

It will just take the necessary amount of memory (works on big files).

mshsayem
  • 17,557
  • 11
  • 61
  • 69
0

If you know your file is in sorted order, you needn't sort it right?

Read the file a line at a time. Keep a window of the last 5 lines read, and read the entire file.

At the end, you'll have the last five lines of the file in ascending order. Now flip them. Now you've got them in descending order.

If you need any range of lines in order, just read the file into RAM and iterate over the range you need.

William Morrison
  • 10,953
  • 2
  • 31
  • 48
0

If the file is large enough, reading the entire file will raise performance issues.

To be efficient you need to use the RandomAccessFile class, and read the file backwards (moving the file pointer to the last character and seeking back until you get your 5 lines).

RandomAccessFile is the way to go when you need to read or manipulate just a slice of a file contents.

samuelgrigolato
  • 192
  • 1
  • 6
0

read your file line by line but keep only the last five lines, use a LinkedList and add the last read line atthe beginning. If after each line the list has more than five lines delete the 5th one:

BufferedReader reader = new BufferedReader(new FileReader(myLog));
String line;
while((line = reader.readLine()) != null) {
    lastLines.add(0, line);
    if(lastLines.size() > 5)
        lastLines.remove(5);
}

// lastLines will have your five lines in reversed order
System.out.println(lastLines);
morgano
  • 17,210
  • 10
  • 45
  • 56
0

Using RandomAccessFile is one of the easiest solution. Point to the end of file, and then read it backwards. This thread lists out the source code for it.

Community
  • 1
  • 1
0

I can't figure out why you are using Thread. I'll try to answer your question anyway with only Java I/O and Util. So if this doesn't fit, use equivalent android dev packages.

public void tail(File in){
    List<String> list = new ArrayList<String>();\\ You could use an Linked List as well
    try {
    Scanner scanner = new Scanner(in).useDelimiter("\n");

    while(scanner.hasNext()){
    String line = scanner.next().trim();
    list.add(line);
    scanner.close();
} 
     catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
}
    for(int i=list.size()-1; i>list.size()-6; i--){
        System.out.println(list.get(i));
    }
}
Aniket
  • 279
  • 3
  • 8
  • 21