用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//结束
大概思路:
属性:
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;
}
}
属性:
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,服务端这边就完事了。
接受客户命令然后发给服务端
接受服务端处理完的数据
用自己的方式呈现给客户(惭愧惭愧)
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();
}
}
}
界面贼丑但是就是随便练个手啦。。。