redis协议支持的数据类型:
相关程序:
一、Protocol
import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class Protocol {
private static String processSimpleString(ProtocolInputStream is) throws IOException {
return is.readLine();
}
private static String processError(ProtocolInputStream is) throws IOException {
return is.readLine();
}
private static long processInteger(ProtocolInputStream is) throws IOException {
return is.readInteger();
}
private static byte[] processBulkString(ProtocolInputStream is) throws IOException {
int len = (int)is.readInteger();
if (len == -1) {
// "$-1\r\n" ==> null
return null;
}
byte[] r = new byte[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(ProtocolInputStream is) throws IOException {
int len = (int)is.readInteger();
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;
}
public static Object read(ProtocolInputStream is) throws IOException {
return process(is);
}
private static Object process(ProtocolInputStream 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 processInteger(is);
case '$':
return processBulkString(is);
case '*':
return processArray(is);
default:
throw new RuntimeException("不识别的类型");
}
}
}
二、Main
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
//InputStream is = System.in;
//String message = "+OK";
//String message = "-ERR unknown command 'put'\r\n";
//String message = ":-100\r\n";
//String message = "$5\r\nhello\r\n";
String message = "*5\r\n$5\r\nlpush\r\n$3\r\nkey\r\n$1\r\n1\r\n$1\r\n2\r\n$1\r\n3\r\n";
ByteInputStream is = new ByteInputStream(message.getBytes(), message.getBytes().length);
List<byte[]> list = (List<byte[]>)Protocol.read(new ProtocolInputStream(is));
for (byte[] b : list) {
System.out.println(new String(b));
}
}
}
三、ProtocolInputStream
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ProtocolInputStream extends FilterInputStream {
/**
* Creates a <code>FilterInputStream</code>
* by assigning the argument <code>in</code>
* to the field <code>this.in</code> so as
* to remember it for later use.
*
* @param in the underlying input stream, or <code>null</code> if
* this instance is to be created without an underlying stream.
*/
public ProtocolInputStream(InputStream in) {
super(in);
}
public String readLine() throws IOException {
boolean needRead = true;
StringBuilder sb = new StringBuilder();
int b = -1;
while (true) {
if (needRead == true) {
b = in.read();
if (b == -1) {
throw new RuntimeException("不应该读到结尾的");
}
} else {
needRead = true;
}
if (b == '\r') {
int c = in.read();
if (c == -1) {
throw new RuntimeException("不应该读到结尾的");
}
if (c == '\n') {
break;
}
if (c == '\r') {
sb.append((char) b);
b = c;
needRead = false;
} else {
sb.append((char) b);
sb.append((char) c);
}
} else {
sb.append((char)b);
}
}
return sb.toString();
}
public long readInteger() throws IOException {
boolean isNegative = false;
StringBuilder sb = new StringBuilder();
int b = in.read();
if (b == -1) {
throw new RuntimeException("不应该读到结尾");
}
if (b == '-') {
isNegative = true;
} else {
sb.append((char)b);
}
while (true) {
b = in.read();
if (b == -1) {
throw new RuntimeException("不应该读到结尾的");
}
if (b == '\r') {
int c = in.read();
if (c == -1) {
throw new RuntimeException("不应该读到结尾的");
}
if (c == '\n') {
break;
}
throw new RuntimeException("没有读到\\r\\n");
} else {
sb.append((char)b);
}
}
long v = Long.parseLong(sb.toString());
if (isNegative) {
v = -v;
}
return v;
}
}