玩具kv数据库

举报
兔老大 发表于 2021/04/19 23:39:19 2021/04/19
2.3k+ 0 0
【摘要】 介绍 用java写一个简陋的kv数据库(俩小时的货),用来复习一下java流知识、线程、socket等知识。 客户端: 很简单的写了一下 功能:就是发送用户的命令,还有接收数据显示出来服务端: redis类:读写和操作数据库(就是封装了一堆map) socket类:接收命令,发送数据打开这两个,然后在客户端打命令即可。 使用规范:*********************...

介绍

用java写一个简陋的kv数据库(俩小时的货),用来复习一下java流知识、线程、socket等知识。


      客户端:
       很简单的写了一下
       功能:就是发送用户的命令,还有接收数据显示出来
      服务端:
       redis类:读写和操作数据库(就是封装了一堆map)
       socket类:接收命令,发送数据
      打开这两个,然后在客户端打命令即可。
      使用规范:
      ***************************************
      create tableName//创建表(最多一百个,可以改)
      例:create stu//创建名为stu的表
      ***************************************
      use tableName//操作表
      例:use stu//操作名字为stu的表
      ***************************************
      showall//打印所有表名
      ***************************************
      增:add key value
      删:delete key
      改:change key
      查:get key
      是否存在:contains key
      ***************************************
      end//结束
  
 

redis.java:

大概思路:

属性:

    private Map<String, String>[] r // 存储所有表
    private String[] tableName//存储所有表名
    private int num = 0;// 表数量
    private int target;// 当前操作的表

方法:

    增删改查

    更换操作的表

    打印

    写入硬盘

    从硬盘读出数据

    接受命令并执行,给反馈


      package redisDemo01;
      import java.io.*;
      import java.util.*;
      public class redis {
      	Scanner in = new Scanner(System.in);
     	private Map<String, String>[] r = new Map[100];// 最多创建100个表
     	private String[] tableName = new String[100];
     	private int num = 0;// 表数量
     	private int target;// 当前操作的表
     	// 创建表
     	public void create(String name) {
      		r[num] = new HashMap<String, String>();
      		tableName[num] = name;
      		target = num;
      		num++;
      	}
     	// 操作表
     	public void use(int target) {
     		this.target = target;
      	}
     	public void use(String name) {
     		for (int i = 0; i < num; i++) {
     			if (tableName[i].equals(name)) {
       target = i;
      break;
      			}
      		}
      	}
     	// 判断是否存在
     	public boolean contains(String key) {
     		return r[target].containsKey(key);
      	}
     	// 增
     	public void add(String key, String value) {
      		r[target].put(key, value);
      	}
     	// 删
     	public void delete(String key) {
      		r[target].remove(key);
      	}
     	// 改
     	public void change(String key, String value) {
      		r[target].put(key, value);
      	}
     	// 查
     	public String get(String key) {
     		return r[target].get(key);
      	}
     	// 打印表
     	public String show() {
      		String ans = "";
     		for (String key : r[target].keySet()) {
      			ans = ans + key + " " + r[target].get(key) + " ";
      		}
     		return ans;
      	}
     	public String showAllTableName() {
      		String anString="";
     		for(int i=0;i<num;i++)
      			anString=anString+i+":"+tableName[i];
     		return anString;
      	}
     	//写入硬盘
     	public void write() {
     		try {
      			Writer writer = new FileWriter(new File("member.txt"));
     			int i=0;//表的下标
     			while (i<num) {
       writer.write("table " + tableName[i] + "\r\n");//表名
      for (String key : r[i].keySet()) {
       writer.write(key + " " + r[i].get(key) + "\r\n");//数据
       }
       i++;
      			}
      			writer.close();
      		} catch (IOException e) {
      			e.printStackTrace();
      		}
      	}
     	//读数据
     	public void read() {
     		try {
      			FileReader fileReader = new FileReader("member.txt");
      			BufferedReader bufferedReader = new BufferedReader(fileReader);
      			String str;
     			while ((str = bufferedReader.readLine()) != null) {
       String[] a = str.split(" ");
      if (a[0].equals("table")) {
       create(a[1]);//新表
       } else {
       add(a[0], a[1]);//表里的数据
       }
      			}
      			bufferedReader.close();
      			fileReader.close();
      		} catch (IOException e) {
      			e.printStackTrace();
      		}
      	}
     	// 接收命令
     	public String command(String aString) {
      		String ans = "success";
      		String[] cmd = aString.split(" ");
     		for (int i = 0; i < cmd.length; i++) {
      			cmd[i] = cmd[i].replaceAll(" ", "");
      		}
      		String command = cmd[0];
     		if (command.equals("create")) {
      			create(cmd[1]);
      		} else if (command.equals("use")) {
      			use(cmd[1]);
      		} else if (command.equals("add")) {
      			add(cmd[1], cmd[2]);
      		} else if (command.equals("contains")) {
     			if (contains(cmd[1]))
       ans = "This key exists";
     			else
       ans = "This key does not exists";
      		} else if (command.equals("get")) {
      			ans = "key:" + cmd[1] + " value:" + get(cmd[1]);
      		} else if (command.equals("delete")) {
      			delete(cmd[1]);
      		} else if (command.equals("show")) {
      			ans = show();
      		} else if (command.equals("showall")) {
      			ans = showAllTableName();
      		} else if (command.equals("end")) {
      			write();
     			return "end";
      		}else {
     			return "false,tryAgain";
      		}
     		return ans;
      	}
      }
  
 

socket.java

属性:

    String cmd;// 命令
    redis r0 // 数据库
    String returnText // 给客户看的信息

方法:

    主要任务是和客户端通信,接受命令,发出客户看到的界面数据。


      package redisDemo01;
      import java.io.*;
      import java.net.*;
      public class socket implements Runnable {
      	String cmd;// 命令
      	redis r0 = new redis();// 数据库
      	String returnText = "success";// 给客户看的信息
     	public void run() {
     		try {
      			r0.read();
      			ServerSocket serverSocket = new ServerSocket(12016);
     			do {
       Socket socket = serverSocket.accept();
       InputStream is = socket.getInputStream();
       OutputStream os = socket.getOutputStream();
      byte[] cache = new byte[1024];
       is.read(cache);
       cmd = new String(cache);
       cmd = cmd.trim();// 去掉多余空格,这个bug调了半天
       System.out.println("redis > " + cmd);
       returnText = r0.command(cmd);//操作数据库
       os.write(returnText.getBytes());// 给客户打印的数据
       os.flush();
       is.close();
       os.close();
      			} while (!returnText.equals("end"));
     			// serverSocket.close();
      		} catch (Exception e) {
      			e.printStackTrace();
      		}
      	}
      }
  
 

然后你run一下socket,服务端这边就完事了。

ClientThread.java

接受客户命令然后发给服务端

接受服务端处理完的数据

用自己的方式呈现给客户(惭愧惭愧)


      package Demo;
      import java.io.*;
      import java.net.*;
      import java.util.*;
      public class ClientThread implements Runnable {
     	@Override
     	public void run() {
     		try {
     			while (true) {
       Scanner s = new Scanner(System.in);
       String temp = s.nextLine();
       Socket socket = new Socket("127.0.0.1", 12016);
      // 获取输入输出流
       InputStream is = socket.getInputStream();
       OutputStream os = socket.getOutputStream();
      // 发送
       os.write(temp.getBytes());
       os.flush();
      // 接收
      byte[] cache = new byte[1024];
       is.read(cache);
       String a = new String(cache);
      if (temp.equals("show")) {//打印所有k——v
       a = a.trim();//去空格
       String[] c = a.split(" ");
      for (int i = 0; i < c.length; i++) {
       c[i] = c[i].replaceAll(" ", "");
       }
      for (int i = 0; i < c.length - 1; i += 2)//依次打印k——v
       System.out.printf("key:%10s value:%10s\n", c[i], c[i + 1]);
       } else
       System.out.println(a);
       os.close();
       socket.close();
      if (temp.equals("end"))
      break;
      			}
      		} catch (Exception e) {
      			e.printStackTrace();
      		}
      	}
      }
  
 

界面贼丑但是就是随便练个手啦。。。

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/92385004

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。