java高效组定长报文续篇3--报文字段分类

  本编文章的基础数据在java高效组定长报文续篇2–准备一些基础数据
中,这里就不重复列举了。上篇文章的两个报文接口字段有几个特点:

  1. 大部分字段都是不含中文的字符串,
  2. 数字型的字符串只有数字和金额
  3. 有些字段的值的长度本身就是固定的
  4. 有些字段是选填的,但是无值时需要占位

报文字段分类

  根据报文字段特点分类

类型编号填充方式说明
普通字符串S右补空格不含中文的字符串
中文字符串C右补空格可含中文的字符串,如名称,附言等
普通数字N左补零一般是整数
浮点型M左补零原始值带小数点,通常组报文时去掉小数点
固定长度字符串F无需填充状态,类型等字段

  做出字段分类的目的,一是减少判断字符串中是否含有中文的判断。二是减少填充字符的次数。只有C型的字符串,才需要处理中文问题,其他类型可直接使用字符数作为字节数。对于F型的字段可以不用计算长度,直接拼到报文中。
  对于像“附言”这种长度比较长,又因为是选填字段,经常没有值。每次都拼一串很长的空格,会降低效率。在前面的章节中,对于这样的字段在系统运行时只拼一次,然后缓存一下,后面直接使用。不直接缓存的原因是字段的长度不固定。

示例

  代码片段中的方法来自 《java高效组定长报文续篇(1)—组定长规则和中文的处理》 和 《java高效组定长报文》中

	/**
	 * 填充一个不含中文的字段
	 * @param value		字段值
	 * @param stdLength	字段标准长度(最大长度)
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static String fillENValue(String value, int stdLength) {
		//要素值的字节数
		int sLength = getEnStringLength(value);
		if (sLength >= stdLength){
			return value;
		}
		//不足的长度
		int restLength = stdLength - sLength;
		//paddingSpacesByCache参看上一篇文章《java高效组定长报文》
		return FixedMsgUtil.paddingSpacesByCache(restLength, value);
	}
	public static int getEnStringLength(String s){
		if(s == null){
			return 0;
		}
		//字符数即字节数
		return s.length();
	}
	/**
	 * 填充一个可能含中文的字段
	 * @param value		字段值
	 * @param stdLength	字段标准长度(最大长度)
	 * @param charset	约定字符集
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static String fillCNValue(String value, int stdLength, String charset) throws UnsupportedEncodingException{
		//要素值的字节数
		int sLength = getCNStringLength(value, charset);
		if (sLength >= stdLength){
			return value;
		}
		//不足的长度
		int restLength = stdLength - sLength;
		//paddingSpacesByCache参看上一篇文章《java高效组定长报文》
		return FixedMsgUtil.paddingSpacesByCache(restLength, value);
	}
	/**
	* 按报文约定字符集获取字符串字节数(用于中文字符串)
	*/
	public static int getCNStringLength(String s, String charset) throws UnsupportedEncodingException{
			if(s == null){
				return 0;
			}
			//charset 报文约定字符集
			return s.getBytes(charset).length;
	}
	/**
	 * 填充一个数字字符串(金额型的去掉小数点后再调用这个方法)
	 * @param value		字段值
	 * @param stdLength	字段标准长度(最大长度)
	 * @return
	 */
	public static String fillMValue(String value, int stdLength) {
		//字段值的字节数
		int sLength = getEnStringLength(value);
		if (sLength >= stdLength){
			return value;
		}
		//不足的长度
		int restLength = stdLength - sLength;
		//paddingSpacesByCache参看上一篇文章《java高效组定长报文》
		return FixedMsgUtil.paddingZerosByCache(restLength, value);
	}
组报文示例1:2020年1月1日往小明的账号A00000000001存款101元
		//示例: 2020年1月1日往小明的账号A00000000001存款101元
		StringBuilder message = new StringBuilder();
		//普通字符串,调用fillENValue
		message.append(fillENValue("2020010100000001", 20));
		//固定长度字符串直接拼
		message.append("T001");
		message.append("01");
		message.append(fillENValue("A00000000001", 32));
		//可含中文的字符串,调用fillCNValue
		message.append(fillCNValue("小明", 20, "GBK"));
		//金额,调用fillMValue
		message.append(fillMValue("10100", 15));
		//可含中文的字符串,调用fillCNValue
		message.append(fillCNValue("", 10, "GBK"));

组报文示例2:20年1月1日小红从账号B00000000002取款202元

//		20年1月1日小红从账号B00000000002取款202元
		StringBuilder message = new StringBuilder();
		//普通字符串,调用fillENValue
		message.append(fillENValue("2020010100000002", 20));
		//固定长度字符串直接拼
		message.append("T001");
		message.append("02");
		message.append(fillENValue("A00000000001", 32));
		//可含中文的字符串,调用fillCNValue
		message.append(fillCNValue("小红", 20, "GBK"));
		//金额,调用fillMValue
		message.append(fillMValue("20200", 15));
		//可含中文的字符串,调用fillCNValue
		message.append(fillCNValue("", 10, "GBK"));

总结

  报文代码示例中,对于不同类型的字段,调用不同的填充方法;大大减少对中文的处理,同时对于一些固定长度的值,也不需要去判断是否需要填充字符,减少了很多不必要的处理。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值