串口操作

本文详细介绍了如何使用Java进行串口通信,包括设置波特率、校验位、停止位等参数,以及发送和接收数据的方法,适用于设备交互或嵌入式系统的控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.iwco.equipment.gsmmodem;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Observable;
import java.util.TooManyListenersException;

/**
 * 串口数据读取类,用于windows的串口数据读取
 * 
 * 
 * @author Macro Lu
 * @version 2007-4-4
 */
public class SerialReader extends Observable implements Runnable,
		SerialPortEventListener {
	static CommPortIdentifier portId;

	int delayRead = 200;
	
	public static String phoneContent = "机房监控";

	int numBytes; // buffer中的实际数据字节数

	private static byte[] readBuffer = new byte[4096]; // 4k的buffer空间,缓存串口读入的数据

	static Enumeration portList;

	InputStream inputStream;
	
	OutputStream out;

	SerialPort serialPort;

	HashMap serialParams;

	// 端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完
	public static final String PARAMS_DELAY = "delay read"; // 延时等待端口数据准备的时间

	public static final String PARAMS_TIMEOUT = "timeout"; // 超时时间

	public static final String PARAMS_PORT = "port name"; // 端口名称

	public static final String PARAMS_DATABITS = "data bits"; // 数据位

	public static final String PARAMS_STOPBITS = "stop bits"; // 停止位

	public static final String PARAMS_PARITY = "parity"; // 奇偶校验

	public static final String PARAMS_RATE = "rate"; // 波特率

	/**
	 * 初始化端口操作的参数.
	 * @see
	 */
	public SerialReader() {
		HashMap<String, Comparable> params = new HashMap<String, Comparable>();
		params.put(SerialReader.PARAMS_TIMEOUT, 1000); // 设备超时时间 1秒
		params.put(SerialReader.PARAMS_DELAY, 200); // 端口数据准备时间 1秒
		params.put(SerialReader.PARAMS_DATABITS, SerialPort.DATABITS_8); // 数据位
		params.put(SerialReader.PARAMS_STOPBITS, SerialPort.STOPBITS_1); // 停止位
		params.put(SerialReader.PARAMS_PARITY, SerialPort.PARITY_NONE); // 无奇偶校验
		serialParams = params;
	}

	public boolean openPort(String ports, int baudrate, String phoneContent) {
		boolean rsBool = false;
		try {
			// 参数初始化
			final int timeout = Integer.parseInt(serialParams.get(PARAMS_TIMEOUT).toString());
			final int rate = baudrate;
			final int dataBits = Integer.parseInt(serialParams.get(PARAMS_DATABITS).toString());
			final int stopBits = Integer.parseInt(serialParams.get(PARAMS_STOPBITS).toString());
			final int parity = Integer.parseInt(serialParams.get(PARAMS_PARITY).toString());
			delayRead = Integer.parseInt(serialParams.get(PARAMS_DELAY).toString());

			final String port = ports;

			// 打开端口
			portId = CommPortIdentifier.getPortIdentifier(port);
			serialPort = (SerialPort) portId.open("SerialReader", timeout);
			inputStream = serialPort.getInputStream();
			out = serialPort.getOutputStream();
			serialPort.addEventListener(this);
			serialPort.notifyOnDataAvailable(true);
			serialPort.setSerialPortParams(rate, dataBits, stopBits, parity);
			rsBool = true;
		} catch (final PortInUseException e) {
			System.out.println("端口已经被占用!");
			e.printStackTrace();
		} catch (final TooManyListenersException e) {
			System.out.println("端口监听者过多!");
			e.printStackTrace();
		} catch (final UnsupportedCommOperationException e) {
			System.out.println("端口操作命令不支持!");
			e.printStackTrace();
		} catch (final NoSuchPortException e) {
			System.out.println("端口不存在!");
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		Thread readThread = new Thread(this);
		readThread.start();
		return rsBool;
	}

	/**
	 * Method declaration
	 * 
	 * 
	 * @see
	 */
	public void run() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
		}
	}
	
	/**
	 * @describe: 向串口写数据 char[] bytes
	 * @date:2009-11-5
	 */
	public void writePort(char[] bytes) throws IOException {
		 int length= bytes.length;
			byte[] sendCmd = new byte[100];
			for (int i = 0; i < length; i++){
				sendCmd[i] = (byte) bytes[i];
			}
				out.write(sendCmd, 0, length);
	}
	
	/**
	 * @describe: 向串口写数据 char[] bytes
	 * @date:2009-11-5
	 */
	public void writePort(String bytes) throws IOException {
		int length = bytes.length();  		 //取得字符串的长度
		byte[] sendCmd = new byte[10000];	//创建一个byte数组
		for(int i=0;i<length;i++){
			sendCmd[i] = (byte) bytes.indexOf(i);
		}
		out.write(sendCmd, 0, length);
	}

	/**
	 * @describe: 向串口写数据 char bytes
	 * @date:2009-11-5
	 */
	public void writePort(char b) throws IOException {
		if (out != null) {
			out.write(b);
			out.flush();
		} else {
		}
	}
	
	/**
	 * @describe: 读取串口数据
	 * @date:2009-11-5
	 */
	public char[] readPackData() throws Exception {
		byte[] readBuffer = new byte[1024];
		char[] msgPack = null;
		int numBytes = 0;

		while (inputStream.available() > 0) {
			numBytes = inputStream.read(readBuffer);
			msgPack = null;
			msgPack = new char[numBytes];
			for (int i = 0; i < numBytes; i++) {
				msgPack[i] = (char) (readBuffer[i] & 0xFF);
			}
		}
		return msgPack;
	}

	/**
	 * Method declaration
	 * 
	 * 
	 * @param event
	 * 
	 * @see
	 */
	public void serialEvent(SerialPortEvent event) {
		try {
			// 等待1秒钟让串口把数据全部接收后在处理
			Thread.sleep(delayRead);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		switch (event.getEventType()) {

		case SerialPortEvent.BI: // 10
		case SerialPortEvent.OE: // 7
		case SerialPortEvent.FE: // 9
		case SerialPortEvent.PE: // 8
		case SerialPortEvent.CD: // 6
		case SerialPortEvent.CTS: // 3
		case SerialPortEvent.DSR: // 4
		case SerialPortEvent.RI: // 5
		case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2
			break;
		case SerialPortEvent.DATA_AVAILABLE: // 1
			try {
				byte[] readBuffer = new byte[500];
				char[] msgPack = null;
				int numBytes = 0;

				while (inputStream.available() > 0) {
					numBytes = inputStream.read(readBuffer);
					msgPack = null;
					msgPack = new char[numBytes];
					for (int i = 0; i < numBytes; i++) {
						msgPack[i] = (char) (readBuffer[i] & 0xFF);
					}
				}
				System.out.println("---" + new String(readBuffer));
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		}
	}
	
	/**
	 * @describe: 列举全部串口名称
	 * @date:2009-11-22
	 */
	public static List<String> getAllComPorts() {
		List<String> comList = new ArrayList<String>();
		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		CommPortIdentifier portIdRs = null;

		while (en.hasMoreElements()) {
			portIdRs = (CommPortIdentifier) en.nextElement();
			if (portIdRs.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				comList.add(portIdRs.getName());
			}
		}
		return comList;
	}
	
	/**
	 * @describe: 关闭串口,释放资源
	 * @date:2009-11-5
	 */
	public void close() {
		if (out != null) {
			try {
				inputStream.close();
				inputStream = null;
			} catch (IOException e) {
			}
		}
		if (serialPort != null) {
			serialPort.close();
			serialPort = null;
		}
	}
}


package com.iwco.equipment.gsmmodem;

import java.util.List;

public class Send {
	
	public static void sendSms(List<String> phoneList,String smsContent,SmsSendJob smsSendJob){
		smsSendJob.sendMessage(phoneList, smsContent);
		smsSendJob.stopService();
	}
}

package com.iwco.equipment.gsmmodem;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;


import com.iwco.dao.IPhone;
import com.iwco.dao.impl.PhoneImpl;
import com.iwco.pojo.Phone;
import com.iwco.pojo.SmsPolicy;


public class SmsSend {
	
	private static IPhone phoneImpl = new PhoneImpl();
	
	private static SmsSendJob smsSendJob;
	
	private static SmsSend smsSend = null;
	
	private SmsSend(String port){
		smsSendJob = SmsSendJob.getInstance();
		smsSendJob.startService(port, 9600, "SMS");
	}
	
	public static SmsSend instance(){
		if (smsSend == null) {
			smsSend = new SmsSend("COM5");
		}
		return smsSend;
	}
	
	public void send(String content){
		//得到搜索条件(查询今天发送的用户)
		SmsPolicy smsPolicy = search();
		//获得手机列表
		List<Phone> phones = phoneImpl.quePhoneByFlag(smsPolicy);
		if(phones.size() != 0){
			//判断是否满足发送条件,删除不满足条件的用户
			List<Phone> phoneSet = check(phones);
			List<String> phoneList = new ArrayList<String>();
			//遍历发送的详情
			Iterator<Phone> iter = phoneSet.iterator();
			while(iter.hasNext()){
System.out.println("发送:'" + content + "'给'" + iter.next().getPhoneNumber() + "'");
				phoneList.add(iter.next().getPhoneNumber());
			}
			smsSendJob.sendMessage(phoneList, content);
		}
	}
	//得到搜索条件(查询今天发送的用户)
	public static SmsPolicy search(){
		SmsPolicy smsPolicy = new SmsPolicy();
		smsPolicy.setMonday(1);smsPolicy.setTuesday(1);
		smsPolicy.setWednesday(1);smsPolicy.setThursday(1);
		smsPolicy.setFriday(1);smsPolicy.setWednesday(1);
		smsPolicy.setSunday(1);
		Calendar c = Calendar.getInstance();
		c.setTime(new Date(System.currentTimeMillis()));
		int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
		switch (dayOfWeek) {
		  case 1:
			  smsPolicy.setSunday(0);
			  break;
		  case 2:
			  smsPolicy.setMonday(0);
			  break;
		  case 3:
			  smsPolicy.setTuesday(0);
			  break;
		  case 4:
			  smsPolicy.setWednesday(0);
			  break;
		  case 5:
			  smsPolicy.setThursday(0);
			  break;
		  case 6:
			  smsPolicy.setFriday(0);
			  break;
		  case 7:
			  smsPolicy.setSaturday(0);
			  break;
		 }
		return smsPolicy;
	}
	
	//检查是否还在上班时间内
	public static boolean checkTime(String startWorking, String endWorking){
		try {
			//格式化时间
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			//得到当前时间
			Date date = new Date();
			//上班时间
			String startWork = df.format(date) + " " + startWorking;
			Date startDate = format.parse(startWork);
			//下班时间
			String endWork = df.format(date) + " " + endWorking;
			Date endDate = format.parse(endWork);
			//返还
			return date.after(startDate) && date.before(endDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	//判断是否满足发送条件
	public static List<Phone> check(List<Phone> phones){
		//发送列表
		List<Phone> phoneSet = new ArrayList<Phone>();
		for (int i = 0; i < phones.size(); i++) {
			Phone phone = phones.get(i);
			//是否只在上班时间发送短信
			if (phone.getSmsPolicy().getWorkTime() == 0) {
				//判断是否是上班时间
				if (checkTime(phone.getSmsPolicy().getStartWork(), phone.getSmsPolicy().getEndWork())) {
					phoneSet.add(phone);
				}
			} else {
				phoneSet.add(phone);
			}
		}
		//返还发送列表
		return phoneSet;
	}
}

package com.iwco.equipment.gsmmodem;

import java.io.IOException;
import java.util.List;

public class SmsSendJob {
	
	private static SmsSendJob smsSendJob = null;
	private SmsSendJob(){};
	private SerialReader serial = new SerialReader();
	private String message;
	
	/**
	 * @describe: 获取SmsSendJob类单例
	 * @date:2011-6-24
	 */
	public static SmsSendJob getInstance() {
		if (smsSendJob == null) {
			smsSendJob = new SmsSendJob();
			return smsSendJob;
		}
		return smsSendJob;
	}
	
	/**
	 * @describe: 测试短信模块(串口号自动检测,不需要设置)
	 * @param baudrate: 串口号
	 * @param baudrate: 波特率
	 * @param passPort: 程序名
	 * @return: true:连接成功,并进入运行状态已经初始化 false:失败 
	 * @date:2011-6-24
	 */
	public boolean startService(String port,int baudrate, String passPort){
		boolean val = serial.openPort(port, 9600, passPort);
		if (val) {
			try {
				//at测试
				message = "at\r";
				serial.writePort(message);
				Thread.sleep(500);
				//信号质量
				message = "AT+CSQ\r+CSQ: 27,99\r";
				serial.writePort(message);
				Thread.sleep(500);
				//报告移动设备的错误
				message = "AT+CMEE=0\r";
				serial.writePort(message);
				Thread.sleep(500);
				//选择消息服务
				message = "AT+CSMS=0\r+CSMS: 1,1,1\r";
				serial.writePort(message);
				Thread.sleep(500);
				//优先信息格式
				message = "AT+CMGF=0\r";
				serial.writePort(message);
				Thread.sleep(500);
				//呼叫线确认陈述
				message = "at+clip=1\r";
				serial.writePort(message);
				Thread.sleep(500);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return val;
	}
	
	/**
	 * @describe: 给指定的一组手机号码,发送短信
	 * @param phoneList 手机号码列表
	 * @param msg 信息内容
	 * @date:2011-6-24
	 * String len = SmsService.toSmsLen("13418167027","请注意,机房温湿度温度高于上限,请及时处理。当前温度:40.0%");
     */
	public void sendMessage(List<String> phoneList, String msg){
		if ( (phoneList != null) && (phoneList.size() > 0) ){
			try {
				for (int i = 0; i < phoneList.size(); i++) {
					//得到信息长度
					String len = SmsService.toSmsLen(phoneList.get(i),msg);
					message = "at+cmgs="+len+"\r";
					serial.writePort(message);
					Thread.sleep(500);
					//发送短信内容
					message = SmsService.toSmsContext(phoneList.get(i),msg);
					serial.writePort(message);
					Thread.sleep(10000);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 停止服务
	 */
	public void stopService(){
		serial.close();
	}
	
//	public static void main(String[] args) throws Exception {
//		SerialReader serial = new SerialReader();
		boolean val = serial.openPort("COM1", 9600, "SMS");
//		if (val) {
//			//at测试
//			String message = "at\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//信号质量
//			message = "AT+CSQ\r+CSQ: 27,99\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//报告移动设备的错误
//			message = "AT+CMEE=0\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//选择消息服务
//			message = "AT+CSMS=0\r+CSMS: 1,1,1\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//优先信息格式
//			message = "AT+CMGF=0\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//呼叫线确认陈述
//			message = "at+clip=1\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//得到信息长度
//			String len = SmsService.toSmsLen("13418167027","1号温湿度,温度高于上限,温度:24.0");
//			message = "at+cmgs="+len+"\r";
//			serial.writePort(message);
//			Thread.sleep(500);
//			//发送短信内容
//			message = SmsService.toSmsContext("13418167027","1号温湿度,温度高于上限,温度:24.0");
//			serial.writePort(message);
//			Thread.sleep(5000);
//			//关闭端口
//			serial.close();
//		}
//	}
	
}

package com.iwco.equipment.gsmmodem;

public class SmsService {

	public static String toSmsContext(String phone,String messages){
		//设置中心号码
		String addr = "00";
//		String addr = "0891683108200005F0";
		//手机号码
		String number = "86" + phone;   //因为在中国所以可以固定为86
		//手机号码长度是否为偶数,如果不是,最后添加F
		if (number.length() % 2 != 0) {
			number = number + "F";
		}
		//手机号码奇数位和偶数位交换
		number = change(number);
		//短信内容
		String msg = message(messages);
		//PDU
		String start = "11000D91";
		String end = "000800";
		
		number = start + number + end + msg;
		//短信的内容
		String message = addr + number + (char)Integer.parseInt("1A",16);
		return message;
	}
	
	//得到长度
	public static String toSmsLen(String phone,String messages){
		//手机号码
		String number = "86" + phone;
		//手机号码长度是否为偶数,如果不是,最后添加F
		if (number.length() % 2 != 0) {
			number = number + "F";
		}
		//手机号码奇数位和偶数位交换
		number = change(number);
		//短信内容
		String msg = message(messages);
		//PDU
		String start = "11000D91";
		String end = "000800";
		number = start + number + end + msg;
		//短信的发送长度
		String len = Integer.toString(number.length() / 2);
		
		return len;
	}
	
	public static String message(String message){
		String msg = CharacterSetToolkit.toUnicode(message, false);
		String len = Integer.toHexString(msg.length() / 2);
		if (len.length() == 1) {
			len = "0" + len;
		}
		return len + msg;		
	}
		
	public static String change(String str){
		StringBuffer sb = new StringBuffer();
		String[] value = new String[str.length()];
		String[] s = str.split("");
		//拆分
		for (int i = 0; i < value.length; i++) {
			value[i] = s[i+1];
		}
		//位置交换
		for (int i = 0; i < value.length;) {
			String temp = value[i];
			value[i] = value[i+1];
			value[i+1] = temp;
			i = i+2;
		}
		//toString
		for (int i = 0; i < value.length; i++) {
			sb.append(value[i]);
		}
		return sb.toString();
	}
}

package com.iwco.equipment.gsmmodem;

/***
*进行字符操作的工具类。
*/
public class CharacterSetToolkit{

	/***//**CreatesanewinstanceofCharacterSetToolkit*/
	public CharacterSetToolkit(){
	}

	private static final char[] hexDigit = {
		'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
	};

	private static char toHex(int nibble){
		return hexDigit[(nibble&0xF)];
	}

	 /**
     * 将字符串编码成 Unicode 。
     * @param theString 待转换成Unicode编码的字符串。
     * @param escapeSpace 是否忽略空格。
     * @return 返回转换后Unicode编码的字符串。
     */
    public static String toUnicode(String theString, boolean escapeSpace) {
        int len = theString.length();
        int bufLen = len * 2;
        if (bufLen < 0) {
            bufLen = Integer.MAX_VALUE;
        }
        StringBuffer outBuffer = new StringBuffer(bufLen);

        for(int x=0; x<len; x++) {
            char aChar = theString.charAt(x);
            // Handle common case first, selecting largest block that
            // avoids the specials below
            if ((aChar > 61) && (aChar < 127)) {
                if (aChar == '\\') {
                    outBuffer.append('\\'); outBuffer.append('\\');
                    continue;
                }
                outBuffer.append(aChar);
                continue;
            }
            switch(aChar) {
                case ' ':
                    if (x == 0 || escapeSpace) 
                        outBuffer.append('\\');
                    outBuffer.append(' ');
                    break;
                case '\t':outBuffer.append('\\'); outBuffer.append('t');
                          break;
                case '\n':outBuffer.append('\\'); outBuffer.append('n');
                          break;
                case '\r':outBuffer.append('\\'); outBuffer.append('r');
                          break;
                case '\f':outBuffer.append('\\'); outBuffer.append('f');
                          break;
                case '=': // Fall through
                case ':': // Fall through
                case '#': // Fall through
                case '!':
                    outBuffer.append('\\'); outBuffer.append(aChar);
                    break;
                case '.':
                    outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '%':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '0':
                    outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '1':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '2':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '3':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '4':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '5':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '6':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '7':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '8':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                case '9':
                	outBuffer.append(toHex((aChar >> 12) & 0xF));
                    outBuffer.append(toHex((aChar >> 8) & 0xF));
                    outBuffer.append(toHex((aChar >> 4) & 0xF));
                    outBuffer.append(toHex( aChar & 0xF));
                    break;
                default:
                    if ((aChar < 0x0020) || (aChar > 0x007e)) {
                        outBuffer.append(toHex((aChar >> 12) & 0xF));
                        outBuffer.append(toHex((aChar >> 8) & 0xF));
                        outBuffer.append(toHex((aChar >> 4) & 0xF));
                        outBuffer.append(toHex( aChar & 0xF));
                    } else {
                        outBuffer.append(aChar);
                    }
            }
        }
        return outBuffer.toString();
    }
    
    /**
     * 从 Unicode 码转换成编码前的特殊字符串。
     * @param in Unicode编码的字符数组。
     * @param off 转换的起始偏移量。
     * @param len 转换的字符长度。
     * @param convtBuf 转换的缓存字符数组。
     * @return 完成转换,返回编码前的特殊字符串。
     */
    public String fromUnicode(char[] in, int off, int len, char[] convtBuf) {
        if (convtBuf.length < len) {
            int newLen = len * 2;
            if (newLen < 0) {
                newLen = Integer.MAX_VALUE;
            }
            convtBuf = new char[newLen];
        }
        char aChar;
        char[] out = convtBuf;
        int outLen = 0;
        int end = off + len;

        while (off < end) {
            aChar = in[off++];
            if (aChar == '\\') {
                aChar = in[off++];
                if (aChar == 'u') {
                    // Read the xxxx
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = in[off++];
                        switch (aChar) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                            value = (value << 4) + aChar - '0';
                            break;
                        case 'a':
                        case 'b':
                        case 'c':
                        case 'd':
                        case 'e':
                        case 'f':
                            value = (value << 4) + 10 + aChar - 'a';
                            break;
                        case 'A':
                        case 'B':
                        case 'C':
                        case 'D':
                        case 'E':
                        case 'F':
                            value = (value << 4) + 10 + aChar - 'A';
                            break;
                        default:
                            throw new IllegalArgumentException(
                                    "Malformed \\uxxxx encoding.");
                        }
                    }
                    out[outLen++] = (char) value;
                } else {
                    if (aChar == 't') {
                        aChar = '\t';
                    } else if (aChar == 'r') {
                        aChar = '\r';
                    } else if (aChar == 'n') {
                        aChar = '\n';
                    } else if (aChar == 'f') {
                        aChar = '\f';
                    }
                    out[outLen++] = aChar;
                }
            } else {
                out[outLen++] = (char) aChar;
            }
        }
        return new String(out, 0, outLen);
    }
    
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值