RandomAccessFile 文件操作(二) 修改文件内容

1 篇文章 0 订阅

1. 使用RandomAccessFile类修改文件内容

1.1 认识RandomAccessFile 类

RandomAccessFile ,随机读写类 。是java输入/输出流体系中功能最丰富的文件访问的类,他提供了众多的方法来访问文件内容,它既可以向读取文件内容,也可以向文件输出数据。与文件的输入/输出不同的是,RandomAccessFile支持“随机访问”的方式,程序可以直接跳转到文件的任意位置来读写数据。

1.2构造方法


  • RandomAccessFile(String name, String mode)
    创建随机访问文件流,以从中指定名称的文件读取,并可选择写入文件。
  • RandomAccessFile(File file, String mode)
    创建一个随机访问文件流从File参数指定的文件中读取,并可选地写入文件。

mode参数

该参数指定RandomAccessFile的访问模式


  • “r” 以只读方式来打开指定文件夹。如果试图对该RandomAccessFile执行写入方法,都将抛出IOException异常。
  • “rw” 以读,写方式打开指定文件。如果该文件尚不存在,则试图创建该文件。
  • “rws” 以读,写方式打开指定文件。相对于”rw” 模式,还要求对文件内容或元数据的每个更新都同步写入到底层设备。
  • “rwd” 以读,写方式打开指定文件。相对于”rw” 模式,还要求对文件内容每个更新都同步写入到底层设备。

1.3 主要方法介绍

   RandomAccessFile类包含了一个记录指针,用以标识当前读写处的位置,当程序新创建一个RandomAccessFile对象时,该对象的文件记录指针位于文件头(也就是0处),当读/写了n个字节后,文件记录指针将会向后移动n个字节。除此之外,RandomAccessFile可以自由的移动记录指针,即可以向前移动,也可以向后移动。RandomAccessFile包含了以下两个方法来操作文件的记录指针.
  
long getFilePointer(); 返回文件记录指针的当前位置

void seek(long pos); 将文件记录指针定位到pos位置

2.实现文件内容的修改

public class MyRandomAccessFile {
/**
     *文件修改
     * @param fileName 文件名称
     * @param oldstr   要修改的字符串
     * @param newStr   新的字符串
     * @return
     */
    //  文件修改 文件内容出现换行就会有错误
    private static boolean modifyFileContent(String fileName, String oldstr, String newStr) {
        ///定义一个随机访问文件类的对象
        RandomAccessFile raf = null;
        try {
            //初始化对象,以"rw"(读写方式)访问文件
            raf = new RandomAccessFile("D:\\" + fileName, "rw");
            //临时变量,存放每次读出来的文件内容
            String line = null;
            // 记住上一次的偏移量
            long lastPoint = 0;
            //循环读出文件内容
            while ((line = raf.readLine()) != null) {
                // 文件当前偏移量 返回文件记录指针的当前位置
                final long point = raf.getFilePointer();
                // 查找要替换的内容
                if (line.contains(oldstr)) {
                    //修改内容,line读出整行数据
                    String str = line.replace(oldstr, newStr);
                    //文件节点移动到文件开始
                    System.out.println(str);
                    raf.seek(lastPoint);
                    raf.writeBytes(str);
                }
                lastPoint = point;//如果文件出现换行,则修改后的节点需要移动到下一行的开头,所以此处会出现错误
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }
     public static void main(String[]args){
        boolean b=modifyFileContent("test.txt","abc","123");
        System.out.println(b);
    }
}

注意:这种方法有它的不足之处:文件修改 文件内容出现换行就会有错误.是因为换行后文件指针造成的,但它可以很方便的在文件的任意位置插入数据,具体方法可以看RandomAccessFile 文件操作(一)任意访问文件内容
解决方法:(已验证正确)

public class MyRandomAccessFile {
    /**
     *文件修改
     * @param filePath 文件名称
     * @param oldstr   要修改的字符串
     * @param newStr   新的字符串
     */
    private static void autoReplace(String filePath, String oldstr, String newStr) {
        //创建文件
        File file = new File(filePath);
        //记录文件长度
        Long fileLength = file.length();
        //记录读出来的文件的内容
        byte[] fileContext = new byte[fileLength.intValue()];
        FileInputStream in = null;
        PrintWriter out = null;
        try {
            in = new FileInputStream(filePath);
            //读出文件全部内容(内容和文件中的格式一致,含换行)
            in.read(fileContext);
            // 避免出现中文乱码
            String str = new String(fileContext, "utf-8");
            //修改对应字符串内容
            str = str.replace(oldstr, newStr);
            //再把新的内容写入文件
            out = new PrintWriter(filePath);
            out.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.flush();
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
public static void main(String[]args){

        autoReplace("D://test.txt","abc","123");//修改文件内容,验证正确
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值