Java 用IO流实现数据储存

一、Java 用IO流实现用户的注册与登录,并且将用户的账号密码储存

  • 从文件中读取存储的用户名和密码,并且实现用户的注册和登录操作。
  • 不使用Propreties类,而是使用IO流中的字节流读取信息,就需要使用String类的split方法,并且提前做好标记符号
  • split方法是将字符串中按指定的符号分割开,比如"123#456",就变成"123",“456”,而且是个数组,所以可以通过split方法先分割开每个用户,然后再分割开每个用户的用户名和密码
  • 这里没有把读取文件中的用户名和密码写成方法,所以在用户注册成功后又复制粘贴了一遍读取操作,看着有点累赘
  • 因为是一个字节一个字节的读取文本,所以不能使用中文注册用户名,会乱码
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;


public class LoginSystemC {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        File file = new File("C:\\Users\\hasee\\Desktop\\JAVA study\\JavaSE\\src\\com\\yaorange\\day18\\userInformationC.ini");
        InputStream inputS = new FileInputStream(file);
        OutputStream outputS = new FileOutputStream(file,true);//不写true的话会导致每次都是覆盖储存文件
       	ArrayList<String> users = new ArrayList<>();
        boolean flag1 = true;
        while (flag1) {//读取每个用户名与密码,以#为结尾,一个字符串一个字符串的写入
            int read;
            StringBuffer sB = new StringBuffer();
            while ((read = inputS.read()) != '#') {
                if (read == -1) {//读到末尾了,跳出
                    flag1 = false;
                    break;
                }
                sB.appendCodePoint(read);
            }
            if(flag1==false)
                break;
            users.add(sB.toString());//将用户写入用户列表
        }
        ArrayList<String> userlist = new ArrayList<>();//用户名列表
        ArrayList<String> pwdlist = new ArrayList<>();//密码列表
        for (String user1 : users) {
            String arr[] = user1.split("-");//将用户名与密码分割开
            userlist.add(arr[0]);
            pwdlist.add(arr[1]);
        }

        boolean flag = true;
        while (flag) {
            System.out.println("1、注册 2、登录 3、退出");
            int x = scanner.nextInt();
            String dontneed = scanner.nextLine();
            switch (x) {
                case 1:
                    System.out.println("请输入用户名:");
                    String username = scanner.nextLine();
                    if (userlist.contains(username)) {
                        System.out.println("用户名存在,不能注册");
                        break;
                    } else {
                        System.out.println("请输入密码:");
                        String pwd = scanner.nextLine();
                        outputS.write((username+"-"+pwd+"#").getBytes());
                        System.out.println("用户注册成功");
                        //刷新刚注册的用户,不然会导致刚注册的用户无法登录
                        users = new ArrayList<>();
                        flag1 = true;
                        while (flag1) {
                            int read;
                            StringBuffer sB = new StringBuffer();
                            while ((read = inputS.read()) != '#') {
                                if (read == -1) {
                                    flag1 = false;
                                    break;
                                }
                                sB.appendCodePoint(read);
                            }
                            if(flag1==false)
                                break;
                            users.add(sB.toString());
                        }
                         userlist = new ArrayList<>();//用户名列表
                        pwdlist = new ArrayList<>();//密码列表
                        for (String user1 : users) {
                            String arr[] = user1.split("-");
                            System.out.println(user1);
                            userlist.add(arr[0]);
                            pwdlist.add(arr[1]);
                        }
                        break;
                    }
                case 2:
                    System.out.println("请输入用户名:");
                    String s1 = scanner.nextLine();
                    if (userlist.contains(s1)) {
                        System.out.println("请输入密码:");
                        String pwdL = scanner.nextLine();
                        if (pwdL.equals(pwdlist.get(userlist.indexOf(s1))))
                            System.out.println("登录成功");
                        else System.out.println("密码输入错误");
                        break;
                    } else {
                        System.out.println("用户名不存在");
                        break;
                    }
                case 3:
                    flag = false;
                    break;
            }

        }
        inputS.close();
        outputS.close();
        scanner.close();
    }
}

二、案例

1. 简易ATM机通过io流存储更改的用户数据
public class FileManager {
    private static final String FILE_NAME = "users.dat";
//ObjectOutputStream 将 List<User> 对象写入到一个名为 users.dat 的文件中。
    public static void saveUsers(List<User> users) {
//创建ObjectOutputStream对象,并将用户列表写入文件。如果发生IOException,会打印信息。
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME))) {
            oos.writeObject(users);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
        //使用 ObjectInputStream 从 users.dat 文件中读取 List<User> 对象。
    public static List<User> loadUsers() {
        List<User> users = new ArrayList<>();
        //创建 ObjectInputStream 对象,并读取用户列表。如果文件未找到,则打印一条消息并初始化一个新的用户列表。
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) {
            users = (List<User>) ois.readObject();
        } catch (FileNotFoundException e) {
            System.out.println("用户数据文件未找到,初始化新数据。");
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("...系统初始化成功");
        return users;	//返回读取的用户列表
    }
}
  • 初始化系统,并在在程序结束前,调用 FileManager.saveUsers(users) 方法,将当前的用户列表保存到文件中。
    public static void main(String[] args) {
        users = FileManager.loadUsers();	//尝试加载用户数据,不存在返回空null
        if (users.isEmpty()) {
            initializeUsers();				//若为空则创建并初始化
        }
        showMainMenu();
        FileManager.saveUsers(users);		//结束前调用 saveUsers(users)
    }

    private static void initializeUsers() {
        users = new ArrayList<>();
        users.add(new User("111111", "111", 12000));
        users.add(new User("222223", "222", 24000));
        users.add(new User("333333", "333", 18500));
        users.add(new User("444444", "444", 15000));
        users.add(new User("555555", "555", 900));
        users.add(new User("666666", "666", 6300));
        users.add(new User("777777", "777", 7200));
        users.add(new User("888888", "888", 18100));
        users.add(new User("999999", "999", 9100));
        users.add(new User("100000", "100", 20000));

    }
2. 简易背包系统存储数据
  1. 创建一个 FileManager 类来处理背包数据的保存和加载。
  2. 修改 Backpack 类,使其在每次更改数据时保存数据,并在初始化时加载数据。
1). 首先,我们定义一个 FileManager 类,用于保存和加载背包数据:
import java.io.*;
import java.util.List;

public class FileManager {
    private static final String FILE_NAME = "backpack.dat";

    public static void saveBackpack(Backpack backpack) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME))) {
            oos.writeObject(backpack);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Backpack loadBackpack() {
        Backpack backpack = null;
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) {
            backpack = (Backpack) ois.readObject();
        } catch (FileNotFoundException e) {
            System.out.println("背包数据文件未找到,初始化新数据。");
            backpack = new Backpack();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("...系统初始化成功");
        return backpack;
    }
}

2). 接下来,修改 Backpack 类,( 也就是你的主类 )使其在每次更改数据时保存数据
'''
    
public class Backpack implements Serializable {		//将需要io操作的类实现Serializable接口
    private List<Slot> slots;
    private Wallet wallet;
    
'''
    
    public void identifyItem(String nameOrId) {
        for (Slot slot : slots) {
            if (slot.getItem() != null && (slot.getItem().getName().equals(nameOrId) || slot.getItem().getId().equals(nameOrId))) {
                if (slot.getItem().isIdentified()) {
                    JOptionPane.showMessageDialog(null, "该物品已被鉴定", "鉴定物品", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    slot.getItem().identify();
                    JOptionPane.showMessageDialog(null, "该物品鉴定完毕", "鉴定物品", JOptionPane.INFORMATION_MESSAGE);
                    //在每次发生数据修改时(增删改)都要调用一次saveBackpack()方法
                    FileManager.saveBackpack(this);		
                }
                return;
            }
        }
        JOptionPane.showMessageDialog(null, "鉴定物品不存在", "鉴定物品", JOptionPane.INFORMATION_MESSAGE);
    }
    
'''
    
3). 更新 Main 类,使其在启动时加载背包数据,并在每次操作后保存数据:
public class Main {
    public static void main(String[] args) {
        // 加载背包数据
        Backpack backpack = FileManager.loadBackpack();

        while (true) {
            String[] options = {"添加物品", "查询所有物品", "查询指定物品", "查询金钱", "鉴定物品", "交易物品", "销毁物品", "整理背包", "扩容背包", "退出"};
            int choice = JOptionPane.showOptionDialog(null, "选择一个操作", "背包系统",
                    JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
            
'''
    

注意:

如果提示错误:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.D0802.BackpackSystem.Backpack.addItem(String, int)" because "backpack" is null
	at org.D0802.BackpackSystem.Main.addItem(Main.java:57)
	at org.D0802.BackpackSystem.Main.main(Main.java:19)
  1. 检查 FileManager:确保 FileManager.loadBackpack() 方法正确返回一个 Backpack 对象。

  2. 检查 Main:确保在 main 方法中正确加载 backpack 对象。

  3. 确保 Backpack 类及其所有依赖类(如 SlotWalletItem 及其子类)都实现了 Serializable 接口。

posted @ 2024-08-03 11:14  用面条吃个鼻子  阅读(77)  评论(3)    收藏  举报