Java基础之删除文本文件中特定行的内容

一、问题的产生

基于I/O流编写的图书馆管理系统

在最近使用I/O流写图书馆管理系统中管理员对图书和用户的管理操作时,遇到了需要删除特定图书和用户的操作,在查询资料和询问老师后得知I/O流中没有可以直接删除单独行的方法。

二、解决思路

同时也为我提供了新的思路:将整个文件中的全部内容读取出来,然后通过集合将每一行单独存放,通过查找到集合内特定的内容后,将该行内容删除,此时list集合会自动将后面的内容填补上来,再重新写入的时候不会出现空行的情况。这时再重新遍历一次该集合,将现在的集合内容写入文件中,此时再看文件,已经完成了删除需要删除的特定行内容了!

三、具体解决方法

下面我以我项目中删除书籍的方法为例,具体讲解该如何解决该问题

先看一下我存入的书籍文件:

通过上图可以看到,我在写入文件时,每一个属性中间添加了一个“,”作为分隔符,这样我们将文件中内容读取到集合之后可以通过split(","); 直接将文件中读出的每行的内容通过数组的形式将每一个属性分隔开,方便我们通过数组下标直接访问相应的属性。

同时由上图可知:此时我的书籍文件中存在7本书籍,除了红楼梦被“张三”借出外,其他书籍均未被借出。

那我们在删除书籍的时候就会遇到一个问题,若我需要删除的书籍是一本被用户借出的书籍在逻辑上我们应该不允许该书籍被删除。所以在程序设计时我们应该避免删除被用户借出后未归还的书籍。

具体判断逻辑如下:

 /**
     * 对书籍.txt文件中特定的书籍进行删除:
     * 1.读出文件中的内容,将其存放在一个String类型的集合中
     * 2.通过分隔符将集合的每一位分割开存放到数组中
     * 3.通过数组下标查找是否有该书籍
     * 否:
     * 输出信息,跳出程序return;
     * 是:
     * 4.通过数组下标查找该书是否有人借阅
     * 是:
     * 输出信息,跳出程序return;
     * 否:
     * 5.通过遍历删除集合中该位所对应的内容
     * 6.将更新后的集合信息写入文件中,完成删除书籍操作
     */

有了程序的具体逻辑之后,我们就可以开始写代码了:

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class DeleteBook {

    private String bookDelete;
    String[] bookinf = new String[8];
    String[] bookinf1 = new String[8];

    public void deleteBook() throws IOException {
        File file = new File("书籍.txt");
        FileInputStream intput = new FileInputStream(file);
        BufferedReader reader = new BufferedReader(new InputStreamReader(intput));
        String tempString;//定义一个字符串,每一次读出该行字符串内容
        List<String> list = new ArrayList<>();//定义一个list字符串集合用来储存每一行的字符串信息
        while ((tempString = reader.readLine()) != null) {
            list.add(tempString);
        }
        System.out.println("==========当前书籍有==========");
        //遍历字符串集合
        for (String book : list) {
            bookinf = book.split(",");//将‘,‘作为分隔符,将字符串分隔开存放进入数组中
            System.out.print(bookinf[0] + " ");
        }
        System.out.println("");
        //输入要删除的内容
        System.out.println("请输入要删除的书籍名称:");
        Scanner scanner = new Scanner(System.in);
        bookDelete = scanner.next();

        //查询该用户是否有未归还的书籍,如果存在未归还的书籍,将不能删除该用户的信息
        FileInputStream inputStream = new FileInputStream(file);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String bookString;
        List<String> bookList = new ArrayList<>();
        while ((bookString = bufferedReader.readLine()) != null) {
            bookList.add(bookString);
        }
        boolean have = false;//是否存在书籍
        for (String borrowUser : bookList) {
            bookinf = borrowUser.split(",");
            //判断书籍是否存在
            if (bookDelete.equals(bookinf[0])) {
                have = true;
            }
            //若该书籍存在,判断书籍对应用户位是否存在用户
            //若对应位用户不为“无”,则表示该书籍有人借出,则无法删除该书籍
            //同时告知管理员(打印)该书籍被哪位用户借出尚未归还
            if (!"无".equals(bookinf[6]) && have) {
                System.out.println("该书籍尚未被用户“" + bookinf[6] + "”归还,请在其归还书籍后再进行操作!");
                return;
            }
        }
        //若书籍不存在,输出相应信息后直接跳出程序
        if (have == false) {
            System.out.println("无法找到该书籍,请重新确认后再进行操作!");
            return;
        }
        for (String delBook : list) {
            bookinf1 = delBook.split(",");
            //找到即将删除的书籍在集合中的位置,将该部分内容从集合中删除,然后清空整个文件
            if (bookDelete.equals(bookinf1[0])) {
                list.remove(delBook);//在集合中删除该行
                FileWriter fd = new FileWriter(file, false);//append传入false表示写入内容时将会覆盖文件中之前存在的内容
                fd.write("");//执行删除操作,写入空内容覆盖之前的内容
                fd.close();
                break;
            }
        }

        //重新遍历一遍更改后的集合,将内容重新写入文件内
        for (String user : list) {
            bookinf1 = user.split(",");
            FileWriter fw = new FileWriter(file, true);//append传入true表示写入内容时将不会覆盖文件中之前存在的内容,将新的内容写在之前内容的后面
            fw.write(bookinf1[0] + "," + bookinf1[1] +
                    "," + bookinf1[2] + "," + bookinf1[3] +
                    "," + bookinf1[4] + "," + bookinf1[5] +
                    "," + bookinf1[6] + "," + bookinf1[7]);//执行重新写入内容的操作,将修改过的集合通过数组读下标后,再重新存写入文件中
            fw.write(System.getProperty("line.separator"));//在段落后添加一个换行符
            fw.close();
        }
        System.out.println("删除成功!");
    }

我们添加一个main方法试运行一下:

public static void main(String[] args) throws IOException {
        DeleteBook db = new DeleteBook();
        db.deleteBook();
    }

运行前文件中的书籍信息:

当我们输入一本未被借出的书籍时:

此时文件中的书籍信息:

可以看到,魔戒已经从文件中消失,在魔戒下一行的霍比特人顶上来了,并未出现空行的情况。

我们再输入一本被借出的书籍,看一看会出现什么情况:

可以看到,输出结果是书籍未被用户张三归还,并且文件中的书籍红楼梦没有被删除。

最后我们来输入一本不存在于文件中的书籍:

因为之前我们将魔戒从文件中删除,此时无法找到该书籍。

四、总结

在java中想要直接通过I/O流中的方法将整个文件中的特定的某一行删除是不行的,此时我们需要转变思路,将I/O流中直接对文件的操作,转换为通过将文件中的内容读到集合中,再对集合进行操作,最后再将集合写入文件中。

到此这篇关于Java基础之删除文本文件中特定行的内容的文章就介绍到这了,更多相关Java中删除文本行的内容内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java迭代器中删除元素的实例操作详解

    我们知道通过Iterator,可以对集合中的元素进行遍历.那么在其中遇到我们不需要的元素时,可不可以在遍历的时候顺便给删除呢?答案是当然可以.在Iterator下有一个remove函数,专门用于删除的操作.下面我们就remove进行讲解,然后对删除元素方法进行说明,最后带来实例的展示. 1.Iterator中的remove void remove():删除迭代器刚越过的元素 从基础集合中移除这个迭代器返回的最后一个元素(可选操作).两个线程中都删除,保证线程的同步. 2.删除元素说明 (1)迭代

  • Java中List遍历删除元素remove()的方法

    今天碰见根据条件进行list遍历remove的问题,第一时间就是简单for循环remove,只知道这么写不行,不安全,可是为什么呢?你想过吗?下面就关于List遍历remove的问题,深挖一下! 一.几种常见的遍历方式 1.普通for循环 2.高级for循环 3.iterator和removeIf 4.stream() 5.复制 6.普通for循环 --> 倒序方式 二.源码篇 1.普通for循环出错原因 public boolean remove(Object o) { if (o == nu

  • Java 添加数字签名到excel及检测,删除签名

    Excel中可添加数字签名以供文档所有者申明文档的所有权或有效性.文本以Java代码示例介绍如何在Excel文档中对数字签名功能进行相关操作,包括如何添加签名到Excel.检测Excel文档是否已签名,以及如何删除Excel文档中的签名. 本次代码测试环境 Excel版本:2013 编译环境:IntelliJ IDEA2018 JDK版本:1.8.0 Excel库工具:spire.xls.jar 4.3.4 Pfx数字证书(及密码) 下面分别以三个代码块来展示如何实现. 1. 添加签名 impo

  • Java实战之基于I/O流设计的图书管理系统

    一.前言 当前,我还没有学到数据库相关的知识,想要完全通过Java来完成一个可以存储数据的图书馆管理系统就只能使用I/O流的知识,将内容都保存到文件中,再进行增删改查的操作,这就很考验我们的Java基础知识掌握能力. 二.项目介绍 Java基本语法的掌握 流程控制语句的熟练使用 面向对象思想的理解 能否熟练使用封装.继承.多态 接口.异常的熟悉 集合的使用 是否熟悉掌握I/O流相关操作 三.项目说明 传统的人工管理图书馆流程繁琐,我们需求设计一个图书馆管理系统来方便学生借书以及管理员管理书籍 系

  • 解决Java Redis删除HashMap中的key踩到的坑

    现象 Java使用Redis删除HashMap中的key时,取出对应的HashMap后通过Java中HashMap的remove方法移除key然后重新调用redis的Hmset方法将覆盖无效 示例代码 //通过key取出对应的HashMap Map<String, String> ruleMap = jedisCluster.hgetAll("HashKey"); //通过java中移除HashMap中的Key ruleMap.remove("ruleA"

  • Java如何通过File类方法删除指定文件夹中的全部文件

    前言 对delete的解说 那么问题来了!!! (②中的问题,怎么删除文件夹里所有文件,想必很多同学也和我一样懵,) 别着急(往下看) 要用到的方法 (递归思想) 如果文件夹里面还有文件夹,就继续往下找(可能不太官方,个人理解) 接下来 代码展示 方法一: package com.study; import java.io.File; import java.io.IOException; /** 1. 应用场景 2. delete删除只能删除空文件夹 和文件 3. 删除指定文件夹 */ pub

  • Java使用RedisTemplate模糊删除key操作

    Redis模糊匹配批量删除操作,使用RedisTemplate操作: public void deleteByPrex(String prex) { Set<String> keys = redisTemplate.keys(prex); if (CollectionUtils.isNotEmpty(keys)) { redisTemplate.delete(keys); } } prex为迷糊匹配的key,如cache:user:* 这里需要判断keys是否存在,如果一个都匹配不到会报错:

  • Java File类的简单使用教程(创建、删除、遍历与判断是否存在等)

    前言 Java文件类以抽象的方式代表文件名和目录路径名.该类本身不能用来读数据或写数据,它主要用于磁盘上文件和目录的创建.文件的查找和文件的删除.做一些非读写方面的工作,比如看看文件是否存在.是否可读写及遍历文件目录等等.要想读写数据,必须和其它io流的类配合使用,比如FileInputStream.FileOutputStream等.File对象代表磁盘中实际存在的文件和目录,以下就通过一些简单的列子介绍File的基本使用. 这是整个File简单使用的代码: 1 package com.tia

  • IDEA插件之快速删除Java代码中的注释

    背景 有时,我们需要删除Java源代码中的注释.目前有不少方法,比如: 实现状态机.该方式较为通用,适用于多种语言(取决于状态机支持的注释符号). 正则匹配.该方式容易误判,尤其是容易误删字符串. 利用第三方库.该方式局限性较强,比如不同语言可能有不同的第三方库. 本文针对Java语言,介绍一种利用第三方库的方式,可以方便快速地移除代码中的注释. 原理 这个第三方库叫做JavaParser.它可以分析Java源码,并生成语法分析树(AST),其中注释也属于AST中的节点. 因此核心思路即为: J

  • 详解Java删除Map中元素java.util.ConcurrentModificationException”异常解决

    今天在使用map并需要根据某些条件删除map元素时,自然而然想到调用Map中的remove(Object key)函数进行删除,代码如下: //遍历map,如果key<5,那么就删除此元素. Map<Integer, Integer> users = new LinkedHashMap<Integer, Integer>(); for (Map.Entry<Integer,Integer> entry : users.entrySet()){ for (int i

随机推荐