package pro.tools.data.text; import com.google.common.collect.Maps; import pro.tools.constant.UnitConst; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.StringTokenizer; /** * 转换相关工具 * * @author SeanDragon */ public final class ToolConvert { private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private ToolConvert() { throw new UnsupportedOperationException("我是工具类,别初始化我。。。"); } /** * byteArr转hexString <p>例如:</p> bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8 * * @param bytes * 字节数组 * * @return 16进制大写字符串 */ public static String bytes2HexString(byte[] bytes) { if (bytes == null) { return null; } int len = bytes.length; if (len <= 0) { return null; } char[] ret = new char[len << 1]; for (int i = 0, j = 0; i < len; i++) { ret[j++] = HEX_DIGITS[bytes[i] >>> 4 & 0x0f]; ret[j++] = HEX_DIGITS[bytes[i] & 0x0f]; } return new String(ret); } /** * hexString转byteArr <p>例如:</p> hexString2Bytes("00A8") returns { 0, (byte) 0xA8 } * * @param hexString * 十六进制字符串 * * @return 字节数组 */ public static byte[] hexString2Bytes(String hexString) { if (ToolStr.isSpace(hexString)) { return null; } int len = hexString.length(); if (len % 2 != 0) { hexString = "0" + hexString; len = len + 1; } char[] hexBytes = hexString.toUpperCase().toCharArray(); byte[] ret = new byte[len >> 1]; for (int i = 0; i < len; i += 2) { ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1])); } return ret; } /** * hexChar转int * * @param hexChar * hex单个字节 * * @return 0..15 */ private static int hex2Dec(char hexChar) { if (hexChar >= '0' && hexChar <= '9') { return hexChar - '0'; } else if (hexChar >= 'A' && hexChar <= 'F') { return hexChar - 'A' + 10; } else { throw new IllegalArgumentException(); } } /** * charArr转byteArr * * @param chars * 字符数组 * * @return 字节数组 */ public static byte[] chars2Bytes(char[] chars) { if (chars == null || chars.length <= 0) { return null; } int len = chars.length; byte[] bytes = new byte[len]; for (int i = 0; i < len; i++) { bytes[i] = (byte) (chars[i]); } return bytes; } /** * byteArr转charArr * * @param bytes * 字节数组 * * @return 字符数组 */ public static char[] bytes2Chars(byte[] bytes) { if (bytes == null) { return null; } int len = bytes.length; if (len <= 0) { return null; } char[] chars = new char[len]; for (int i = 0; i < len; i++) { chars[i] = (char) (bytes[i] & 0xff); } return chars; } /** * 以unit为单位的内存大小转字节数 * * @param memorySize * 大小 * @param unit * 单位类型 <ul> <li>{@link UnitConst.MemoryUnit#BYTE}: 字节</li> <li>{@link UnitConst.MemoryUnit#KB} : 千字节</li> * <li>{@link UnitConst.MemoryUnit#MB} : 兆</li> <li>{@link UnitConst.MemoryUnit#GB} : GB</li> </ul> * * @return 字节数 */ public static long memorySize2Byte(long memorySize, UnitConst.MemoryUnit unit) { if (memorySize < 0) { return -1; } switch (unit) { default: case BYTE: return memorySize; case KB: return memorySize * UnitConst.KB; case MB: return memorySize * UnitConst.MB; case GB: return memorySize * UnitConst.GB; } } /** * 字节数转以unit为单位的内存大小 * * @param byteNum * 字节数 * @param unit * 单位类型 <ul> <li>{@link UnitConst.MemoryUnit#BYTE}: 字节</li> <li>{@link UnitConst.MemoryUnit#KB} : 千字节</li> * <li>{@link UnitConst.MemoryUnit#MB} : 兆</li> <li>{@link UnitConst.MemoryUnit#GB} : GB</li> </ul> * * @return 以unit为单位的size */ public static double byte2MemorySize(long byteNum, UnitConst.MemoryUnit unit) { if (byteNum < 0) { return -1; } switch (unit) { default: case BYTE: return (double) byteNum; case KB: return (double) byteNum / UnitConst.KB; case MB: return (double) byteNum / UnitConst.MB; case GB: return (double) byteNum / UnitConst.GB; } } /** * 字节数转合适内存大小 <p>保留3位小数</p> * * @param byteNum * 字节数 * * @return 合适内存大小 */ public static String byte2FitMemorySize(long byteNum) { if (byteNum < 0) { return "shouldn't be less than zero!"; } else if (byteNum < UnitConst.KB) { return String.format("%.3fB", byteNum + 0.0005); } else if (byteNum < UnitConst.MB) { return String.format("%.3fKB", byteNum / UnitConst.KB + 0.0005); } else if (byteNum < UnitConst.GB) { return String.format("%.3fMB", byteNum / UnitConst.MB + 0.0005); } else { return String.format("%.3fGB", byteNum / UnitConst.GB + 0.0005); } } /** * 以unit为单位的时间长度转毫秒时间戳 * * @param timeSpan * 毫秒时间戳 * @param unit * 单位类型 <ul> <li>{@link UnitConst.TimeUnit#MSEC}: 毫秒</li> <li>{@link UnitConst.TimeUnit#SEC }: 秒</li> * <li>{@link UnitConst.TimeUnit#MIN }: 分</li> <li>{@link UnitConst.TimeUnit#HOUR}: 小时</li> <li>{@link * UnitConst.TimeUnit#DAY }: 天</li> </ul> * * @return 毫秒时间戳 */ public static long timeSpan2Millis(long timeSpan, UnitConst.TimeUnit unit) { switch (unit) { default: case MSEC: return timeSpan; case SEC: return timeSpan * UnitConst.SEC; case MIN: return timeSpan * UnitConst.MIN; case HOUR: return timeSpan * UnitConst.HOUR; case DAY: return timeSpan * UnitConst.DAY; } } /** * 毫秒时间戳转以unit为单位的时间长度 * * @param millis * 毫秒时间戳 * @param unit * 单位类型 <ul> <li>{@link UnitConst.TimeUnit#MSEC}: 毫秒</li> <li>{@link UnitConst.TimeUnit#SEC }: 秒</li> * <li>{@link UnitConst.TimeUnit#MIN }: 分</li> <li>{@link UnitConst.TimeUnit#HOUR}: 小时</li> <li>{@link * UnitConst.TimeUnit#DAY }: 天</li> </ul> * * @return 以unit为单位的时间长度 */ public static long millis2TimeSpan(long millis, UnitConst.TimeUnit unit) { switch (unit) { default: case MSEC: return millis; case SEC: return millis / UnitConst.SEC; case MIN: return millis / UnitConst.MIN; case HOUR: return millis / UnitConst.HOUR; case DAY: return millis / UnitConst.DAY; } } /** * 毫秒时间戳转合适时间长度 * * @param millis * 毫秒时间戳 <p>小于等于0,返回null</p> * @param precision * 精度 <ul> <li>precision = 0,返回null</li> <li>precision = 1,返回天</li> <li>precision = 2,返回天和小时</li> * <li>precision = 3,返回天、小时和分钟</li> <li>precision = 4,返回天、小时、分钟和秒</li> <li>precision >= * 5,返回天、小时、分钟、秒和毫秒</li> </ul> * * @return 合适时间长度 */ public static String millis2FitTimeSpan(long millis, int precision) { if (millis <= 0 || precision <= 0) { return null; } StringBuilder sb = new StringBuilder(); String[] units = {"天", "小时", "分钟", "秒", "毫秒"}; int[] unitLen = {86400000, 3600000, 60000, 1000, 1}; precision = Math.min(precision, 5); for (int i = 0; i < precision; i++) { if (millis >= unitLen[i]) { long mode = millis / unitLen[i]; millis -= mode * unitLen[i]; sb.append(mode).append(units[i]); } } return sb.toString(); } /** * bytes转bits * * @param bytes * 字节数组 * * @return bits */ public static String bytes2Bits(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte aByte : bytes) { for (int j = 7; j >= 0; --j) { sb.append(((aByte >> j) & 0x01) == 0 ? '0' : '1'); } } return sb.toString(); } /** * bits转bytes * * @param bits * 二进制 * * @return bytes */ public static byte[] bits2Bytes(String bits) { int lenMod = bits.length() % 8; int byteLen = bits.length() / 8; // 不是8的倍数前面补0 if (lenMod != 0) { StringBuilder bitsBuilder = new StringBuilder(bits); for (int i = lenMod; i < 8; i++) { bitsBuilder.insert(0, "0"); } bits = bitsBuilder.toString(); byteLen++; } byte[] bytes = new byte[byteLen]; for (int i = 0; i < byteLen; ++i) { for (int j = 0; j < 8; ++j) { bytes[i] <<= 1; bytes[i] |= bits.charAt(i * 8 + j) - '0'; } } return bytes; } /** * inputStream转outputStream * * @param is * 输入流 * * @return outputStream子类 */ public static ByteArrayOutputStream input2OutputStream(InputStream is) throws IOException { if (is == null) { return null; } try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { byte[] b = new byte[UnitConst.KB]; int len; while ((len = is.read(b, 0, UnitConst.KB)) != -1) { os.write(b, 0, len); } return os; } } /** * inputStream转byteArr * * @param is * 输入流 * * @return 字节数组 */ public static byte[] inputStream2Bytes(InputStream is) throws IOException { if (is == null) { return null; } return input2OutputStream(is).toByteArray(); } /** * byteArr转inputStream * * @param bytes * 字节数组 * * @return 输入流 */ public static InputStream bytes2InputStream(byte[] bytes) { if (bytes == null || bytes.length <= 0) { return null; } return new ByteArrayInputStream(bytes); } /** * outputStream转byteArr * * @param out * 输出流 * * @return 字节数组 */ public static byte[] outputStream2Bytes(OutputStream out) { if (out == null) { return null; } return ((ByteArrayOutputStream) out).toByteArray(); } /** * outputStream转byteArr * * @param bytes * 字节数组 * * @return 字节数组 */ public static OutputStream bytes2OutputStream(byte[] bytes) throws IOException { if (bytes == null || bytes.length <= 0) { return null; } try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { os.write(bytes); return os; } } /** * inputStream转string按编码 * * @param is * 输入流 * @param charsetName * 编码格式 * * @return 字符串 */ public static String inputStream2String(InputStream is, String charsetName) throws IOException { if (is == null || ToolStr.isSpace(charsetName)) { return null; } return new String(inputStream2Bytes(is), charsetName); } /** * string转inputStream按编码 * * @param string * 字符串 * @param charsetName * 编码格式 * * @return 输入流 */ public static InputStream string2InputStream(String string, String charsetName) throws UnsupportedEncodingException { if (string == null || ToolStr.isSpace(charsetName)) { return null; } return new ByteArrayInputStream(string.getBytes(charsetName)); } /** * outputStream转string按编码 * * @param out * 输出流 * @param charsetName * 编码格式 * * @return 字符串 */ public static String outputStream2String(OutputStream out, String charsetName) throws UnsupportedEncodingException { if (out == null || ToolStr.isSpace(charsetName)) { return null; } return new String(outputStream2Bytes(out), charsetName); } /** * string转outputStream按编码 * * @param string * 字符串 * @param charsetName * 编码格式 * * @return 输入流 */ public static OutputStream string2OutputStream(String string, String charsetName) throws IOException { if (string == null || ToolStr.isSpace(charsetName)) { return null; } return bytes2OutputStream(string.getBytes(charsetName)); } /** * outputStream转inputStream * * @param out * 输出流 * * @return inputStream子类 */ public static ByteArrayInputStream output2InputStream(OutputStream out) { if (out == null) { return null; } return new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray()); } public static Map<String, String> str2map(String str, String tokenStr, String splitStr) { StringTokenizer tokenSTK = new StringTokenizer(str, tokenStr); Map<String, String> result = Maps.newHashMapWithExpectedSize(tokenSTK.countTokens()); while (tokenSTK.hasMoreTokens()) { String nextStr = tokenSTK.nextToken(); StringTokenizer splitSTK = new StringTokenizer(nextStr, splitStr); if (splitSTK.countTokens() == 2) { result.put(splitSTK.nextToken(), splitSTK.nextToken()); } } return result; } public static String map2str(Map<String, Object> params, String middleStr, String endStr) { StringBuilder result = new StringBuilder(); params.forEach((key, value) -> { result.append(key).append(middleStr).append(value.toString()).append(endStr); }); return result.toString(); } }