本文代码传入文件地址返回如代码块:
为了更好的拓展,我把foo.c这个文件名拓展成了6个字节用来表示版本号如1.2.66.c
后四个字节用来存储文件长度
也就是说第0帧数据为 SOH 00 FF 1.2.66 1236542 NUL[118] CRC CRC
当然我最后返回的都是10进制的byte数组 可以直接netty发送
代码:
package com.ruoyi.netty.netty;
import com.ruoyi.netty.netty.domain.ByteUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.FileCopyUtils;
import java.io.*;
/**
* @ClassName: Ymodem
* @Description: Ymodem协议工具类
* @author ns
* @date 2021-10-18 14:25
* @Copyright 873103468@qq.com
*/
public class Ymodem {
/**
* byte[]文件转Ymodem协议文件
* @param file
* @return
*/
public static byte[][] BytesYmodem(byte[] file,double len,String name){
byte[] bytestr = name.getBytes();
int a=1;
int b=254;
int ys=(int)Math.ceil(len/128.00);
if(bytestr.length!=6){
return null;
}
byte[][] bytess=new byte[ys+1][133];
bytess[0]=ymodem_0(bytestr,len);
for (int bl=1;bl<ys;bl++){
bytess[bl]=ymodemTobyte(file,bl,a,b,(int)len);
a++;
b--;
}
return bytess;
}
/***
* 把文件地址转换成byte二维数组 二维数组例子
* (例子未转换实际已经转换)
* SOH 00 FF 00~00(共128个) CRCH CRCL
* SOH 01 FE 00~00(共128个) CRCH CRCL
* SOH 02 FD 00~00(共128个) CRCH CRCL
* SOH 03 FC 00~00(共128个) CRCH CRCL
* EOT
* EOT
* SOH 00 FF FUL[128] CRCH CRCL
* @param path 文件地址
* @return 最终数据
*/
public static byte[][] getStringByteYmodem(String path){
if (StringUtils.isNotEmpty(path)) {
File file = new File(path);
byte[] byte1 = fileToBinArray(file);
int len=byte1.length;
return BytesYmodem(byte1,len,getFileNameNoEx(file.getName()));
}else {
throw new RuntimeException("文件找不到地址");
}
}
/**
* 文件转为二进制数组
* @param file
* @return
*/
public static byte[] fileToBinArray(File file){
try {
InputStream fis = new FileInputStream(file);
byte[] bytes = FileCopyUtils.copyToByteArray(fis);
return bytes;
}catch (Exception ex){
throw new RuntimeException("文件转为二进制数组出错",ex);
}
}
/**
* 第一帧
* @param bytestr
* @param len
* @return
*/
public static byte[] ymodem_0(byte[] bytestr,double len){
//第一页
byte[] b0= new byte[3];
b0[0]=0x01;
b0[1]=(byte) 00;
b0[2]=(byte) 255;
byte[] b1= new byte[128];
ByteUtil.getByte2inByte1(b1,bytestr,0);
byte[] b3= new byte[4];
ByteUtil.putInt(b3,(int)len,0);
ByteUtil.getByte2inByte1(b1,b3,6);
ByteUtil.inMaxByte(b1,10);
byte[] b5=ByteUtil.getByte1andByte2(b1,CRC.getCRC5(b1));
return ByteUtil.getByte1andByte2(b0,b5);
}
/**
* 第n帧数据
* @param file 文件
* @param bl 第几行
* @param a 01
* @param b FF
* @param len 长度
* @return
*/
public static byte[] ymodemTobyte(byte[] file,int bl,int a,int b,int len){
byte[] b0= new byte[3];
b0[0]=0x01;
b0[1]=(byte) a;
b0[2]=(byte) b;
byte[] sj= new byte[128];
//判断剩余长度是否大于128时
int lening=(bl-1)*128;
int xhint =lening;
if(len-lening<128){
for (int f=0;f<len-lening;f++){
sj[f]=file[xhint];
xhint++;
}
ByteUtil.inMaxByte(sj,len-lening);
}else {
for (int f=0;f<128;f++){
sj[f]=file[xhint];
xhint++;
}
}
byte[] sj1=ByteUtil.getByte1andByte2(sj,CRC.getCRC5(sj));
return ByteUtil.getByte1andByte2(b0,sj1);
}
public static void main(String[] args) {
System.out.println(getFileNameNoEx("1.2.66.c"));
}
/**
* Java文件操作 获取文件扩展名
*/
public static String getExtensionName(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot >-1) && (dot < (filename.length() - 1))) {
return filename.substring(dot + 1);
}
}
return filename;
}
/**
* Java文件操作 获取不带扩展名的文件名
*/
public static St