RandomAccessFile通过指定的字节长度读取文件,通过Netty传输到服务端,然后写入文件,,但是文件乱码,,是怎么回事,能帮忙解决一下吗?不胜感激

孙士林 发布于 2018/10/17 14:01
阅读 734
收藏 0

【Gopher China万字分享】华为云的Go语言云原生实战经验!>>>

package test;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

import com.common.ClientDTO;

public class FileUploadClientHandler extends ChannelInboundHandlerAdapter {
    private volatile int byteRead;
    private volatile int start = 0;
    private volatile int lastLength = 0;
    private volatile short count =0;
    public static volatile RandomAccessFile randomAccessFile;
    private volatile ClientDTO fileUploadFile;//可能线程不安全

    public FileUploadClientHandler(ClientDTO ef) {
        if (ef.getFile().exists()) {
            if (!ef.getFile().isFile()) {
                System.out.println("Not a file :" + ef.getFile());
                return;
            }
        }
        this.fileUploadFile = ef;
    }

    //客户端连接成功就会出发此函数
    public void channelActive(ChannelHandlerContext ctx) {
        try {
            count++;
            randomAccessFile = new RandomAccessFile(fileUploadFile.getFile(), "r");
            randomAccessFile.seek(fileUploadFile.getStarPos());
            lastLength = (int) randomAccessFile.length() / 10;
            
//            FileRegion f = new DefaultFileRegion(randomAccessFile.getChannel(), fileUploadFile.getStarPos(), lastLength);
//            MappedByteBuffer buffer = f.map(  
//                    f.MapMode.READ_ONLY, 0, f.size());  
            byte[] bytes = new byte[lastLength];
            System.out.println("-------------第"+count+"次传输的字节长度----------" + bytes.length);
            if ((byteRead = randomAccessFile.read(bytes)) != -1) {
                fileUploadFile.setEndPos(byteRead);
                fileUploadFile.setBytes(bytes);
                ctx.writeAndFlush(fileUploadFile);
            } else {
                System.out.println("文件已经读完");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException i) {
            i.printStackTrace();
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof Integer) {
            count++;
            start = (Integer) msg;
            if (start != -1) {
                // RandomAccessFile rdafile = new RandomAccessFile(path, "rw");
                // FileRegion f = new DefaultFileRegion(rdafile.getChannel(), 0,
                // rdafile.length());
                 randomAccessFile.seek(start);
                 System.out.println("每次读取的长度:" + (randomAccessFile.length() / 10));
                 System.out.println("长度:" + (randomAccessFile.length() - start));
                int a = (int) (randomAccessFile.length() - start);
                int b = (int) (randomAccessFile.length() / 10);
                if (a < b) {
                    lastLength = a;
                    }
                byte[] bytes = new byte[lastLength];
                System.out.println("-------------第"+count+"次传输的字节长度----------" + bytes.length);
                if ((byteRead = randomAccessFile.read(bytes)) != -1 
                        && (randomAccessFile.length() - start) > 0) {
                    System.out.println("byte 长度:" + bytes.length);
                    fileUploadFile.setEndPos(byteRead);
                    fileUploadFile.setBytes(bytes);
                    System.out.println("===============byteRead:"+byteRead);
                    try {
                        ctx.writeAndFlush(fileUploadFile);
                    } catch (Exception e) {
                        e.printStackTrace();
                        }
                    } else {
                        System.out.println("传输完成关闭RandomAccessFile");
                    randomAccessFile.close();
                    /**
                     * 这里ctx需要flush因为后面需要进行心跳检测
                     */
                    ctx.flush();
                    System.out.println("文件已经读完--------" + byteRead);
                    //这里需要进行监控
                }
            }
        }
    }

   
/**这里有多少个Handler就会执行多少次
 * 
 */
     @Override
     public void channelReadComplete(ChannelHandlerContext ctx) throws
     Exception {
         System.out.println("channelReadComplete =======方法执行");
         ctx.flush();
     }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
    // @Override
    // protected void channelRead0(ChannelHandlerContext ctx, String msg)
    // throws Exception {
    // String a = msg;
    // System.out.println("This is"+
    // ++counter+"times receive server:["+msg+"]");
    // }
    // @Override
    // public void channelRead(ChannelHandlerContext ctx, Object msg) throws
    // Exception {
    // System.out.println("Server is speek :"+msg.toString());
    // FileRegion filer = (FileRegion) msg;
    // String path = "E://Apk//APKMD5.txt";
    // File fl = new File(path);
    // fl.createNewFile();
    // RandomAccessFile rdafile = new RandomAccessFile(path, "rw");
    // FileRegion f = new DefaultFileRegion(rdafile.getChannel(), 0,
    // rdafile.length());
    //
    // System.out.println("This is" + ++counter + "times receive server:["
    // + msg + "]");
    // }
    

}
/**服务端的Handler

package test;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.File;
import java.io.RandomAccessFile;
import java.text.NumberFormat;
import com.common.ClientDTO;
/**
 * 文件传输处理类
 * bug(编码问题,RandomAccessFile)
 * @author 士林
 *
 */
public class FileUploadServerHandler extends ChannelInboundHandlerAdapter {
    private int byteRead;
    private volatile int start = 0;
    private volatile int size =0;
    private String file_dir = "D:";
    private static volatile RandomAccessFile randomAccessFile;
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelActive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ClientDTO) {
            ClientDTO ef = (ClientDTO) msg;
            byte[] bytes = ef.getBytes();
            
            byteRead = ef.getEndPos();
            //这里是判断是否将配置文件传给服务端
            if(ef.getClientLogo()==null||!ef.getClientLogo().equals("192.168.8.52")){
//                System.out.println(ef.getClientLogo());
                System.out.println("没有获取到文件的客户端ip---------------");
            }
            String path = file_dir + File.separator + ef.getClientLogo()+File.separator+ef.getFileClientName();
            System.out.println("服务端的path==================="+path);
            File file = new File(path);
            //判断目标文件所在的目录是否存在
            if(!file.getParentFile().exists()) {
                //如果目标文件所在的目录不存在,则创建父目录
                System.out.println("目标文件所在目录不存在,准备创建它!");
                if(!file.getParentFile().mkdirs()) {
                    System.out.println("创建目标文件所在目录失败!");
                    }
                }
            //创建文件后如果数据长度为0
            if (bytes.length==0) {
                return ;
            }
            //这里还需要加判断文件是否存在,start的值是否为正确的
            if(start==0||!file.exists()){
                
                randomAccessFile = new RandomAccessFile(file, "rw");//第一次初始化
                randomAccessFile.seek(start);
                randomAccessFile.write(bytes);
                start = start + byteRead;
                size = (int)ef.getLength() ;
                start = start + byteRead;
                // 创建一个数值格式化对象  
                NumberFormat numberFormat = NumberFormat.getInstance();  
                // 设置精确到小数点后2位  
                numberFormat.setMaximumFractionDigits(2);  
                String result = numberFormat.format((float) start / (float) size * 100);  
                System.out.println("文件大小:"+size/1024+"KB");
                System.out.println("start:=====文件传输了:"+start/1024+"KB");
                System.out.println("已接受文件:"+result+"%");
                if (start < size) {
                    ctx.writeAndFlush(start);
                } else{
                    System.out.println("当前byteRead的值="+byteRead);
                    System.out.println("传输有问题");
                    randomAccessFile.close();
                    ctx.flush();
                }
            }else{
            randomAccessFile.seek(start);
            randomAccessFile.write(bytes);
            start = start + byteRead;
            // 创建一个数值格式化对象  
            NumberFormat numberFormat = NumberFormat.getInstance();  
            // 设置精确到小数点后2位  
            numberFormat.setMaximumFractionDigits(2);
            String result = numberFormat.format((float) start / (float) size * 100);  
            System.out.println("文件大小:"+size/1024+"KB");
            System.out.println("start:=====文件传输了:"+start/1024+"KB");
            System.out.println("已接受文件:"+result+"%");
            if (start<size) {
                ctx.writeAndFlush(start);
                } else {
                    System.out.println("传输完成关闭RandomAccessFile");
                randomAccessFile.close();
                System.out.println("还会占用此文件,不过可读!");
                ctx.flush();
                }
            }
        }
    }

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

加载中
0
独孤晓林

看看文件编码,一般都是读取文件时给的编码不对

0
手牽着手

指定对应的文件编码格式

返回顶部
顶部