java 根据分隔符从后往前读取文件数据
思路
- 从前往后比较简单,使用Scanner的
sc.useDelimiter(delimiter);
就可以。 - 从后往前 百度了半天似乎java没有从后往前读的api 唯一沾一点边的
RandomAccessFile
里面有方法可以移动光标到任意位置,但是这种适合读取最后一行之类的,不适合使用分隔符。思来想去还是使用Scanner,但是做一点处理,由于我的需求明确读取多少,所以思路是开辟一个字符串数组存储当前最新从文件读取的数据(只要明确要读多少数据,数组会比链表时间空间复杂度强不少,相反如果不明确大小一定要用链表),使用下标取余方式记录数据,在用一个字段记录是否超过一次遍历,具体看代码。
实现代码
从后往前读代码
private static String useDelimiterFromBack(File file, String delimiter
, int readRow) {
String[] showData = new String[readRow];
int index = 0;
boolean isBeyondReadRow = false;
try (Scanner sc = new Scanner(new FileReader(file))) {
sc.useDelimiter(delimiter);
while (sc.hasNext() && readRow > 0) {
String str = sc.next();
showData[index++] = str;
if (index >= readRow) {
isBeyondReadRow = true;
index %= readRow;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return "read error";
}
StringBuilder result = new StringBuilder(readRow);
for (int i = index - 1; i >= 0; i--) {
result.append(showData[i]);
}
if (isBeyondReadRow) {
for (int i = readRow - 1; i >= index; i--) {
result.append(showData[i]);
}
} else {
result.append(LOAD_ALL_DATA_MSG);
}
return result.toString();
}
FileUtil
package com.jtexplorer.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class FileUtil {
public final static int FROM_BACK = 0;
public final static int FROM_FRONT = 1;
private final static String LOAD_ALL_DATA_MSG = "\n*****已加载全部数据!*****\n";
public static String getDataUseDelimiter(File file, String delimiter
, int readRow, Integer orientation) {
if (!file.exists() && !file.isFile()) {
return null;
}
if (readRow <= 0) {
return null;
}
switch (orientation) {
case FileUtil.FROM_FRONT:
return useDelimiterFromFront(file, delimiter, readRow);
case FileUtil.FROM_BACK:
return useDelimiterFromBack(file, delimiter, readRow);
default:
return null;
}
}
private static String useDelimiterFromFront(File file, String delimiter
, int readRow) {
StringBuilder showData = new StringBuilder();
try (Scanner sc = new Scanner(new FileReader(file))) {
sc.useDelimiter(delimiter);
while (sc.hasNext() && readRow > 0) {
String str = sc.next();
showData.append(str);
readRow--;
}
if (!sc.hasNext()) {
showData.append(LOAD_ALL_DATA_MSG);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return showData.toString();
}
private static String useDelimiterFromBack(File file, String delimiter
, int readRow) {
String[] showData = new String[readRow];
int index = 0;
boolean isBeyondReadRow = false;
try (Scanner sc = new Scanner(new FileReader(file))) {
sc.useDelimiter(delimiter);
while (sc.hasNext() && readRow > 0) {
String str = sc.next();
showData[index++] = str;
if (index >= readRow) {
isBeyondReadRow = true;
index %= readRow;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return "read error";
}
StringBuilder result = new StringBuilder(readRow);
for (int i = index - 1; i >= 0; i--) {
result.append(showData[i]);
}
if (isBeyondReadRow) {
for (int i = readRow - 1; i >= index; i--) {
result.append(showData[i]);
}
} else {
result.append(LOAD_ALL_DATA_MSG);
}
return result.toString();
}
}