java 根据分隔符从后往前读取文件数据

该博客介绍了如何使用Java从后往前读取文件数据,特别是在需要按分隔符处理数据时。作者提供了一个实现,利用Scanner类结合字符串数组来模拟逆向读取,并通过一个布尔标志判断是否超出预设读取行数。代码中包括了从后往前读取的完整实现,以及在读取完毕后的数据组装策略。
摘要由CSDN通过智能技术生成

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) {
        //超过了一行 将剩余的readRow-index个数据放入
            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;

/**
 * 文件读取类
 *
 * @author yuge
 */
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";

    /**
     * 使用确定的分隔符读取数据
     *
     * @param file        file
     * @param delimiter   分隔符
     * @param readRow     读取多少
     * @param orientation 方向
     * @return String
     */
    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) {
        //超过了一行 将剩余的readRow-index个数据放入
            for (int i = readRow - 1; i >= index; i--) {
                result.append(showData[i]);
            }
        } else {
            result.append(LOAD_ALL_DATA_MSG);
        }

        return result.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值