【Java小项目】redis-like

项目描述

本项目主要是一个单线程的实现了redis一些命令的内存数据库。主要采用maven对项目实施代码管理,通过I/O流实现对命令的读取和输出。实现了对于redis的数据传输协议的解析以及对于lists、hashes中的命令进行了实现,如lpush、lpop、lrange、hset、hget等。

关键字

redis、协议解析、I/O、Socket、网络、TCP

源代码

Protocal.java
主要用于对redis数据传输协议的解析。

package com.niu;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

public class Protocol {
   
    public static Object read(InputStream is) throws IOException {
   
        return process(is);
    }

    //读命令
    public static Command readCommand(InputStream is) throws Exception {
   
        Object o  = read(is);
        // 作为 Server 来说,一定不会收到 "+OK\r\n"
        if (!(o instanceof List)) {
   
            throw new Exception("命令必须是 Array 类型");
        }

        //将读取到的命令保存在List中
        List<Object> list = (List<Object>)o;
        if (list.size() < 1) {
   
            throw new Exception("命令元素个数必须大于 1");
        }

        //删除掉前面的命令单词
        Object o2 = list.remove(0);
        if (!(o2 instanceof byte[])) {
   
            throw new Exception("错误的命令类型");
        }

        byte[] array = (byte[])o2;
        String commandName = new String(array);
        String className = String.format("com.niu.commands.%sCommand", commandName.toUpperCase());
        Class<?> cls = Class.forName(className);
        //
        if (!Command.class.isAssignableFrom(cls)) {
   
            throw new Exception("错误的命令");
        }
        Command command = (Command)cls.newInstance();
        command.setArgs(list);

        return command;
    }

    //读到的是Simple String类型的处理方式
    private static String processSimpleString(InputStream is) throws IOException {
   
        return readLine(is);
    }

    //解析error
    private static String processError(InputStream is) throws IOException {
   
        return readLine(is);
    }
    //读到的是integer类型的处理方式
    private static long processInteger(InputStream is) throws IOException {
   
        return readInteger(is);
    }
    //读到的是BulkString类型的处理方式
    private static byte[] processBulkString(InputStream is) throws IOException {
   
        int len = (int)readInteger(is);
        if (len == -1) {
   
            // "$-1\r\n"    ==> null
            return null;
        }

        byte[] r = new byte[len];
        is.read(r, 0, len);
        /*
        for (int i = 0; i < len; i++) {
            int b = is.read();
            r[i] = (byte)b;
        }
        */

        // "$5\r\nhello\r\n";
        is.read();
        is.read();

        return r;
    }

    private static List<Object> processArray(InputStream is) throws IOException {
   
        int len = (int)readInteger(is);
        if (len == -1) {
   
            // "*-1\r\n"        ==> null
            return null;
        }

        List<Object> list = new ArrayList<>(len);
        for (int i = 0; i < len; i++) {
   
            try {
   
                list.add(process(is));
            } catch (RemoteException e) {
   
                list.add(e);
            }
        }

        return list;
    }
    //判断输入数据的类型
    private static Object process(InputStream is) throws IOException {
   
        int b = is.read();
        if (b == -1) {
   
            throw new RuntimeException("不应该读到结尾的");
        }

        switch (b) {
   
            case '+':
                return processSimpleString(is);
            case '-':
                throw new RemoteException(processError(is));
            case ':':
                return 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值