网络编程--(七)压缩文件代码

本文介绍了一个使用Netty实现的文件压缩与传输的应用案例。该案例包括文件的GZIP压缩与解压方法,并通过Netty在服务器与客户端之间传输压缩后的文件。此外,还展示了如何在Netty中设置事件处理器来处理消息。
复制代码
package bhz.netty.test4;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipUtils {
    
    /**
     * 压缩文件
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] gzip(byte[] data) throws Exception{
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        GZIPOutputStream gzip=new GZIPOutputStream(bos);
        gzip.write(data);
        gzip.finish();
        gzip.close();
        byte[] ret=bos.toByteArray();
        bos.close();
        return ret;
        
    }
    
    /**
     * 解压文件
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] ungzip(byte[] data) throws Exception{
        ByteArrayInputStream bis=new ByteArrayInputStream(data);
        GZIPInputStream gzip=new GZIPInputStream(bis);
        byte[] buf=new byte[1024];
        int num=-1;
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        while((num=gzip.read(buf,0,buf.length))!=-1){
            bos.write(buf,0,num);
        }
        gzip.close();
        bis.close();
        byte[] ret=bos.toByteArray();
        bos.flush();
        bos.close();
        return ret;
    }
    
    public static void main(String[] args) throws Exception {
        //读取文件
        String readPath=System.getProperty("user.dir")+File.separatorChar+"sources"+File.separatorChar+"001.jpg";
        System.out.println(readPath);
        
        File file=new File(readPath);
        FileInputStream in=new FileInputStream(file);
        byte[] data=new byte[in.available()];   
        in.read(data);
        in.close();
        System.out.println("文件原始大小:"+data.length);
        
        //测试压缩
        byte[] ret1=GzipUtils.gzip(data);
        System.out.println("压缩后的文件大小:"+ret1.length);
        
        byte[] ret2=GzipUtils.ungzip(ret1);
        System.out.println("还原后的文件大小:"+ret2.length);
        
        //写出文件
        String writePath=System.getProperty("user.dir")+File.separatorChar+"receive"+File.separatorChar+"001.jpg"; 
        FileOutputStream fos=new FileOutputStream(writePath);
        fos.write(ret2);
        fos.close();
        
    }
}
复制代码

 

复制代码
package bhz.netty.test4;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class Server {

    public static void main(String[] args) throws Exception {
        //1 第一个线程组 是用于接收Client端连接的
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //2 第二个线程组 是用于实际的业务处理操作的
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        
        //3 创建一个辅助类Bootstrap,就是对我们的Server进行一系列的配置
        ServerBootstrap b = new ServerBootstrap(); 
        //把俩个工作线程组加入进来
        b.group(bossGroup, workerGroup)
        //我要指定使用NioServerSocketChannel这种类型的通道
         .channel(NioServerSocketChannel.class)
        //一定要使用 childHandler 去绑定具体的 事件处理器
         .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
                sc.pipeline().addLast(new ServerHandler());
            } 
        });

        //绑定指定的端口 进行监听
        ChannelFuture f = b.bind(8765).sync(); 
        
        
        //Thread.sleep(1000000);
        f.channel().closeFuture().sync();   //等待关闭
    
        
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
         
        
        
    }
    
}
复制代码
复制代码
package bhz.netty.test4;

import java.io.File;
import java.io.FileOutputStream;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

public class ServerHandler  extends ChannelHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    
            /*//do something msg
            ByteBuf buf = (ByteBuf)msg; 
            byte[] data = new byte[buf.readableBytes()];
            buf.readBytes(data);
            String request = new String(data, "utf-8");
            System.out.println("Server: " + request);
            //写给客户端
            String response = "我是反馈的信息";
            ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes()))
            .addListener(ChannelFutureListener.CLOSE);   //当服务器端写完客户端收到后断开客户端连接
*/            
            
            /*String request = (String)msg; 
            System.out.println("Server: " + request);
            //写给客户端
            String response = "我是反馈的信息$_";
            ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
            //.addListener(ChannelFutureListener.CLOSE);   //当服务器端写完客户端收到后断开客户端连接
*/            
        
            Req req=(Req)msg;
            System.out.println("server:"+req.getId()+" ,"+req.getName()+","+ req.getRequestMessage());
            
            byte[] attachement=GzipUtils.ungzip(req.getAttachment());
            String writePath=System.getProperty("user.dir")+File.separatorChar+"receive"+File.separatorChar+"001.png"; 
            FileOutputStream fos=new FileOutputStream(writePath);
            fos.write(attachement);
            fos.close();
            
            Resp resp=new Resp();
            resp.setId(req.getId());
            resp.setName("resp"+req.getId());
            resp.setResponseMessage("响应内容"+req.getId());
            ctx.writeAndFlush(resp);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}
复制代码
复制代码
package bhz.netty.test4;

import java.io.File;
import java.io.FileInputStream;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class Client {

    public static void main(String[] args) throws Exception {
        
        EventLoopGroup workgroup = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(workgroup)
        .channel(NioSocketChannel.class)
        .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
                
                sc.pipeline().addLast(new ClientHandler());
            }
        });
        
        ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync();
        
        
        //写入
        /*cf1.channel().writeAndFlush(Unpooled.copiedBuffer("bbb$_".getBytes()));
        cf1.channel().writeAndFlush(Unpooled.copiedBuffer("ccc$_".getBytes()));*/
        for(int i=0;i<2;i++){
            Req req=new Req();
            req.setId(""+i);
            req.setName("pro"+i);
            req.setRequestMessage("数据信息"+i);
            
            //制定路径的文件转换为压缩流
            String path=System.getProperty("user.dir")+File.separatorChar+"sources"+File.separatorChar+"001.png";
            File file=new File(path);
            FileInputStream in=new FileInputStream(file);
            byte[] data=new byte[in.available()];
            in.read(data);
            in.close();
            req.setAttachment(GzipUtils.gzip(data));
            
            cf1.channel().writeAndFlush(req);
        }
        
        
        cf1.channel().closeFuture().sync();
        
        workgroup.shutdownGracefully();
        
    }
}
复制代码
复制代码
package bhz.netty.test4;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

public class ClientHandler extends ChannelHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            //do something msg
            /*ByteBuf buf = (ByteBuf)msg;
            byte[] data = new byte[buf.readableBytes()];
            buf.readBytes(data);
            String request = new String(data, "utf-8");
            System.out.println("Client: " + request);*/
            
        /*    String response=(String)msg;
            System.out.println("Client: "+response);*/
            
            Resp resp=(Resp)msg;
            System.out.println("client:"+resp.getId()+" ,"+resp.getName()+","+ resp.getResponseMessage());
            
            
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
复制代码

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值