All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.utils.BinaryUtils Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
/**   
* @Title: StreamUtilits.java 
* @Package net.gdface.utils 
* @Description: guyadong 
* @author guyadong   
* @date 2014-10-21 上午10:51:32 
* @version V1.0   
*/
package net.gdface.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 二进制数据(byte[],ByteBuffer)工具类
 * @author guyadong
 *
 */
public class BinaryUtils {
	private static final String MD5_REGEX = "^[a-fA-F0-9]{32}$";
	private static final String HEX_REGEX  = "^([a-fA-F0-9]{2})+$";
	/**
	 * 生成MD5校验码
	 * 
	 * @param source
	 * @return MD5 byte array
	 */
	public static final byte[] getMD5(byte[] source) {
		if (null ==source){
			return null;
		}
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			return md.digest(source);
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 返回buffer中所有字节(position~limit),不改变buffer状态
	 * @param buffer
	 * @return buffer 为 null 时返回 null 
	 */
	public static final byte[] getBytesInBuffer(ByteBuffer buffer){
		if(null == buffer){
			return null;
		}
		int pos = buffer.position();
		try{
			byte[] bytes = new byte[buffer.remaining()];
			buffer.get(bytes);
			return bytes;
		}finally{
			buffer.position(pos);
		}
	}
	/**
	 * 生成MD5校验码
	 * @param source
	 * @return MD5 ByteBuffer
	 * @see #getMD5(byte[])
	 */
	public static final ByteBuffer getMD5(ByteBuffer source) {
		return null == source ?null:ByteBuffer.wrap(getMD5(getBytesInBuffer(source)));
	}
	/**
	 * 将16位byte[] 转换为32位的HEX格式的字符串String
	 * 
	 * @param buffer
	 * @return HEX string
	 */
	public static final String toHex(byte[] buffer) {
		if (null == buffer){
			return null;
		}
		StringBuffer sb = new StringBuffer(buffer.length * 2);
		for (int i = 0; i < buffer.length; i++) {
			sb.append(Character.forDigit((buffer[i] & 240) >> 4, 16));
			sb.append(Character.forDigit(buffer[i] & 15, 16));
		}
		return sb.toString();
	}
	/** @see #toHex(byte[]) */
	public static final String toHex(ByteBuffer buffer) {
		return toHex(getBytesInBuffer(buffer));  
	}
	/**
	 * 字符串验证器,根据正则表达式判断字符串是否为十六进制(HEX)字符串
	 * 输入为null或空或正则表达式不匹配则返回false
	 */
	public static final boolean validHEX(String input){
		return input != null && input.matches(HEX_REGEX);
	}
    /**
     * convert HEX string to byte array
     * @param src
     * @return byte array or {@code null} if src is {@code null}
     */
    public static final byte[] hex2Bytes(String src){
    	if(null == src){
    		return null;
    	}
        byte[] res = new byte[src.length()/2];  
        char[] chs = src.toCharArray();  
        int[] b = new int[2];  
  
        for(int i=0,c=0; i='0' && chs[i+j]<='9'){  
                    b[j] = (chs[i+j]-'0');  
                }else if(chs[i+j]>='A' && chs[i+j]<='F'){  
                    b[j] = (chs[i+j]-'A'+10);  
                }else if(chs[i+j]>='a' && chs[i+j]<='f'){  
                    b[j] = (chs[i+j]-'a'+10);  
                }  
            }   
              
            b[0] = (b[0]&0x0f)<<4;  
            b[1] = (b[1]&0x0f);  
            res[c] = (byte) (b[0] | b[1]);  
        }  
          
        return res;  
    } 
    /**
     * convert HEX string to ByteBuffer
     * @param src
     * @return byte array or {@code null} if src is {@code null}
     */
    public static final ByteBuffer hex2ByteBuffer(String src){
    	return null == src?null:ByteBuffer.wrap(hex2Bytes(src));
    }
	/**
	 * 生成MD5校验码字符串
	 * 
	 * @param source
	 * @return MD5 HEX string
	 * @see #getMD5(byte[])
	 * @see #toHex(byte[])
	 */
    public static final String getMD5String(byte[] source) {
		return toHex(getMD5(source));
	}
	/**
	 * 生成MD5校验码字符串
	 * 
	 * @param source
	 * @return MD5 HEX string
	 * @see #getMD5(byte[])
	 * @see #toHex(byte[])
	 */
    public static final String getMD5String(ByteBuffer source) {
		return toHex(getMD5(source));
	}
	/**
	 * 判断是否为有效的MD5字符串
	 * @return true/false
	 */
	public static final boolean validMd5(String md5){
		return null != md5 && md5.matches(MD5_REGEX);
	}
	/**
	 * 从{@link InputStream}读取字节数组
* 当{@code in}为{@link FileInputStream}时,调用{@link #readBytes(FileInputStream)}(NIO方式)读取
* 结束时会关闭{@link InputStream} * @param in 为{@code null}返回{@code null} * @return 读取的字节数组 * @throws IOException * @throws IllegalArgumentException {@code in}为{@code null} */ public static final byte[] readBytes(InputStream in) throws IOException, IllegalArgumentException { if(null == in){ return null; } if(in instanceof FileInputStream){ return readBytes((FileInputStream)in); } try { int buffSize = Math.max(in.available(), 1024*8); byte[] temp = new byte[buffSize]; ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize); int size = 0; while ((size = in.read(temp)) != -1) { out.write(temp, 0, size); } return out.toByteArray(); } finally { in.close(); } } /** * NIO方式从{@link FileInputStream}读取字节数组
* 结束时会关闭{@link InputStream} * @param fin {@link FileInputStream} * @return 返回读取的字节数 当{@code fin}为null时返回null; * @throws IOException */ public static final byte[] readBytes(FileInputStream fin) throws IOException { if(null == fin){ return null; } FileChannel fc = fin.getChannel(); try { ByteBuffer bb = ByteBuffer.allocate((int) fc.size()); fc.read(bb); bb.flip(); return bb.array(); } finally { if (null != fc){ fc.close(); } fin.close(); } } /** * 将对象转换为InputStream
* 类型可以是byte[],{@link ByteBuffer},{@link InputStream},{@link String}(base64编码),{@link File},{@link URL},{@link URI},否则抛出RuntimeException
* * @param src * 获取InputStream的源对象 * @return 返回获取的InputStream对象,src为{@code null}返回{@code null},类型错误抛出异常 * @throws IOException * @throws IllegalArgumentException 无法从{@code src}获取{@link InputStream} */ public static final InputStream getInputStream(T src) throws IOException, IllegalArgumentException { if(null == src){ return null; } if (src instanceof InputStream){ return (InputStream) src; }else if (src instanceof String) { return new ByteArrayInputStream(Base64Utils.decode(((String) src))); } else if (src instanceof byte[]) { return new ByteArrayInputStream((byte[]) src); } else if (src instanceof ByteBuffer) { return new ByteArrayInputStream(getBytesInBuffer((ByteBuffer) src)); } else if (src instanceof File) { return new FileInputStream((File) src); } else if (src instanceof URL) { return ((URL) src).openStream(); } else if (src instanceof URI) { return ((URI) src).toURL().openStream(); } else{ throw new IllegalArgumentException(String.format("Can't get inputstream from [%s]", src.getClass() .getCanonicalName())); } } /** * 将数据对象{@code src}转换为字节数组(byte[])
* {@code src}的数据类型可以是byte[],{@link InputStream},{@link ByteBuffer},{@link String}(base64编码),{@link File},{@link URL},{@link URI} * 否则抛出{@link IllegalArgumentException}
* 对象转换为InputStream或byte[]时,可能会抛出{@link IOException} * * 当{@code src}为{@link File}或{@link FileInputStream}时,使用NIO方式({@link #readBytes(FileInputStream)})读取 * * @param src * 获取byte[]的源对象 * @return 返回字节数组,参数为{@code null}返回{@code null},类型不对则抛出异常 * @throws IOException * @throws IllegalArgumentException {@code src}为{@code null}或无法从{@code src}获取{@link InputStream} * @see #readBytes(InputStream) * @see #readBytes(FileInputStream) * @see #getInputStream(Object) * @see Base64Utils#decode(String) */ public static final byte[] getBytes(T src) throws IOException, IllegalArgumentException { if(null==src){ return null; } if (src instanceof byte[]) { return (byte[]) src; } else if (src instanceof String) { return Base64Utils.decode(((String) src)); } else if (src instanceof ByteBuffer) { return getBytesInBuffer((ByteBuffer)src); } else if (src instanceof FileInputStream){ return readBytes((FileInputStream)src); }else if (src instanceof File){ return readBytes(new FileInputStream((File)src)); }else { return readBytes(getInputStream(src)); } } /** * 调用 {@link #getBytes(Object)}返回非空字节数组
* 如果返回{@code null}或空字节数组,则抛出{@link IOException}
* @param src 获取byte[]的源对象 * @return 返回非空字节数组 * @throws IOException * @see #getBytes(Object) */ public static final byte[] getBytesNotEmpty(T src) throws IOException { byte[] imgData = getBytes(src); if (imgData == null || imgData.length == 0){ throw new IOException(String.format("return null or zero length from %s", src.getClass() .getSimpleName())); } return imgData; } /** * 将数据对象src转换为{@link ByteBuffer} * @param src 获取byte[]的源对象 * @return 返回字节数组,参数为{@code null}返回{@code null},类型不对则抛出异常 * @throws IOException * @throws IllegalArgumentException 无法从{@code src}获取{@link InputStream} * @see #getBytes(Object) */ public static final ByteBuffer getByteBuffer(T src) throws IOException, IllegalArgumentException { return src == null ? null : ByteBuffer.wrap(getBytes(src)); } /** * 调用 {@link #getByteBuffer(Object)}返回非空{@link ByteBuffer}
* 如果返回{@code null}或空,则抛出{@link IOException}
* @param src * @return 返回非空字节数组 * @throws IOException * @throws IllegalArgumentException */ public static final ByteBuffer getByteBufferNotEmpty(T src) throws IOException, IllegalArgumentException { return ByteBuffer.wrap(getBytesNotEmpty(src)); } /** * NIO方式将{@code data}数据保存在{@code file}指定的文件中
* 如果{@code file}所在文件夹不存在,则会自动创建所有的文件夹
* @param data * @param file 文件保存的位置 * @param overwrite 同名文件存在时是否覆盖 * @return 返回保存的文件名 * @throws IOException {@code file}存在但不是文件或其他IO异常 * @throws IllegalArgumentException {@code data}为null时 */ public static final File saveBytes(byte[] data, File file, boolean overwrite) throws IOException, IllegalArgumentException { if(data == null){ throw new IllegalArgumentException("data is null"); } FileOutputStream out = null; FileChannel fc = null; try { File folder = file.getParentFile(); if (!folder.exists()){ folder.mkdirs(); } long free = folder.getFreeSpace()>>20;//可用磁盘空间(MB) if(free<10){ throw new IOException(String.format("DISK ALMOST FULL(磁盘空间不足) FREE %dMB,%s",free,folder.getAbsolutePath())); } if (!file.exists() || !file.isFile() || overwrite) { out = new FileOutputStream(file); fc = out.getChannel(); ByteBuffer bb = ByteBuffer.wrap(data); fc.write(bb); } return file; } finally { if (null != fc){ fc.close(); } if (null != out){ out.close(); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy