public class ChatCodec extends ByteToMessageCodec<ChatMessage> {
@Override
protected void encode(ChannelHandlerContext channelHandlerContext, ChatMessage chatMessage, ByteBuf out) throws Exception {
System.out.println("开始编码");
out.writeInt(chatMessage.getMagic());
out.writeByte(chatMessage.getVersion());
out.writeByte(chatMessage.getType());
out.writeByte(chatMessage.getCharset());
if(chatMessage.getType()==0){
out.writeInt(chatMessage.getContentSize());
out.writeBytes(chatMessage.getContent().getBytes());
}else {
out.writeInt(chatMessage.getNameSize());
out.writeCharSequence(chatMessage.getNameTail(),StandardCharsets.UTF_8);
out.writeInt(chatMessage.getContentSize());
out.writeCharSequence(chatMessage.getContent(),StandardCharsets.UTF_8);
out.writeLong(chatMessage.getDataSize());
FileChannel fileChannel = new FileInputStream(chatMessage.getContent()).getChannel();
System.out.println(System.currentTimeMillis());
long c = 0;
long size = chatMessage.getDataSize();
while (size>100){
// 写入数据会自动 扩容 从256 256*2 256*2*2 .......
System.out.println(out.writerIndex()+" "+ out.capacity());
size = size-100;
int i = out.writeBytes(fileChannel, c, 100);
System.out.println(out.isWritable());
c=c+100;
}
out.writeBytes(fileChannel,c, (int) size);
fileChannel.close();
System.out.println("文件发送完毕");
}
}
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
System.out.println("开始解码");
ChatMessage chatMessage = new ChatMessage();
chatMessage.setMagic(in.readInt()).setVersion(in.readByte())
.setType(in.readByte()).setCharset(in.readByte());
if(chatMessage.getType() == 0){
chatMessage.setContentSize(in.readInt());
CharSequence charSequence = in.readCharSequence(chatMessage.getContentSize(), StandardCharsets.UTF_8);
chatMessage.setContent(charSequence.toString());
out.add(chatMessage);
}else {
chatMessage.setNameSize(in.readInt());
chatMessage.setNameTail(in.readCharSequence(chatMessage.getNameSize(),StandardCharsets.UTF_8).toString());
chatMessage.setContentSize(in.readInt());
CharSequence charSequence = in.readCharSequence(chatMessage.getContentSize(), StandardCharsets.UTF_8);
chatMessage.setContent(charSequence.toString());
chatMessage.setDataSize(in.readLong());
out.add(chatMessage);
String path ="C:\\Users\\艾桑\\Desktop\\数据生成器\\netty\\netty-50000\\src\\main\\resources\\static\\download\\";
File file1 = new File(path);
if(file1.isDirectory()){
file1.mkdirs();
}
File file = new File(path + UUID.randomUUID() + chatMessage.getNameTail());
try {
file.createNewFile();
}catch (Exception e){
e.printStackTrace();
}
long size = chatMessage.getDataSize();
FileChannel fileChannel = new FileOutputStream(file).getChannel();
// 输出到文件只能输出剩下的字节数, 输出后不能扩容 ByteBuf为不可读状态 reader和writer都为2048
// 那么请问如何读取剩下的数据呢? 急
while (size>0){
try {
if(!in.isReadable()){
in.markWriterIndex();
}
int i = in.readBytes(fileChannel,in.readableBytes());
size =size -i;
}catch (Exception e){
e.printStackTrace();
}
}
fileChannel.close();
System.out.println(System.currentTimeMillis());
System.out.println("文件接收完毕");
}
}