//SM2 package com.lzy.gm; import org.bouncycastle.asn1.gm.GMObjectIdentifiers; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.*; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.util.encoders.Hex; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.ECGenParameterSpec; /** * 国密sm2算法 * 参考链接:https://blog.csdn.net/qq_39120741/article/details/130937860 */ public class SM2 { private final KeyPair mKeyPair; public SM2() throws Exception { mKeyPair = initKey(); } /** * sm2加密算法 * @param pubkey:公钥 * @param plainData:要加密的字符串 * @return:加密结果 */ public static String encrypt(PublicKey pubkey,String plainData) { try { SM2Engine sm2Engine = MySm2Engine.createMySm2Engine(pubkey,null,MySm2Engine.Type_Encode); //encrypt data byte[] bytes = null; try { byte[] in = plainData.getBytes(StandardCharsets.UTF_8); bytes = sm2Engine.processBlock(in,0, in.length); } catch (Exception e) { System.out.println("SM2加密失败:"); } return Hex.toHexString(bytes); }catch (Exception e) { e.printStackTrace(); } return null; } /** * sm2解密算法 * @param priKey:私钥 * @param cipherData:要解密的字符串 * @return */ public static String decrypt(PrivateKey priKey,String cipherData) { try { //init engine SM2Engine sm2Engine = MySm2Engine.createMySm2Engine(null,priKey,MySm2Engine.Type_Decode); //decrypt data byte[] cipherDataByte = Hex.decode(cipherData); byte[] bytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length); return new String(bytes, StandardCharsets.UTF_8); }catch (Exception e) { System.out.println("SM2解密失败:"); } return null; } /** * 创建密钥对 * 原文链接:https://blog.csdn.net/liranke/article/details/128814638 * @return 密钥对KeyPair * @throws Exception */ public static KeyPair initKey() throws Exception{ try { ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1"); // 获取一个椭圆曲线类型的密钥对生成器 final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider()); // 使用SM2参数初始化生成器 kpg.initialize(sm2Spec); // 获取密钥对 KeyPair keyPair = kpg.generateKeyPair(); return keyPair; }catch (Exception e) { throw new Exception(e); } } /** * 签名 * * @param data * @param privateKey * @return * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public static String sign(String data, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { // 生成SM2sign with sm3 签名验签算法实例 Signature signature = Signature.getInstance( GMObjectIdentifiers.sm2sign_with_sm3.toString(), new BouncyCastleProvider()); // 签名 // 签名需要使用私钥,使用私钥 初始化签名实例 signature.initSign(privateKey); // 写入签名原文到算法中 signature.update(data.getBytes(StandardCharsets.UTF_8)); // 计算签名值 byte[] signatureValue = signature.sign(); return Hex.toHexString(signatureValue); } /** * 验签 * * @param publicKey * @param plainText * @param signatureValue * @return * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public static boolean verify(PublicKey publicKey, String plainText, String signatureValue) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { // 生成SM2sign with sm3 签名验签算法实例 Signature signature = Signature.getInstance( GMObjectIdentifiers.sm2sign_with_sm3.toString(), new BouncyCastleProvider()); /* * 验签 * 签名需要使用公钥,使用公钥 初始化签名实例 */ signature.initVerify(publicKey); // 写入待验签的签名原文到算法中 signature.update(plainText.getBytes(StandardCharsets.UTF_8)); // 验签 return signature.verify(Hex.decode(signatureValue)); } public static void main(String[] args) throws Exception { String dataStr = "hello ,2023!"; SM2 sm2CryptTools= new SM2(); KeyPair keyPair = sm2CryptTools.mKeyPair; System.out.println("原始明文:" + dataStr); String resData = sm2CryptTools.encrypt(keyPair.getPublic(),dataStr); System.out.println("SM2加密后密文:" + resData); String resData2 = sm2CryptTools.decrypt(keyPair.getPrivate(),resData); System.out.println("SM2解密后明文:" + resData2); String sign = sign(dataStr, keyPair.getPrivate()); System.out.println("签名值:" + sign); System.out.println("dataStr:" + dataStr); boolean verify = verify(keyPair.getPublic(), dataStr, sign); System.out.println("验签结果:" + verify); } } /** * SM2引擎类 */ class MySm2Engine { public static final int Type_Encode = 0; public static final int Type_Decode = 1; /** * 创建一个SM2引擎 * @param pubKey * @param priKey * @param enOrde * @return * @throws Exception */ public static SM2Engine createMySm2Engine(PublicKey pubKey,PrivateKey priKey,int enOrde) throws Exception { if (enOrde == Type_Encode) { ECPublicKeyParameters ecPublicKeyParameters = null; if (pubKey instanceof BCECPublicKey) { BCECPublicKey bcPubKey = (BCECPublicKey) pubKey; ECParameterSpec ecParameterSpec = bcPubKey.getParameters(); ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(), ecParameterSpec.getG(), ecParameterSpec.getN()); ecPublicKeyParameters = new ECPublicKeyParameters(bcPubKey.getQ(),ecDomainParameters); } SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom())); return sm2Engine; }else { BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) priKey; ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters(); ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(), ecParameterSpec.getG(), ecParameterSpec.getN()); ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(), ecDomainParameters); SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(false, ecPrivateKeyParameters); return sm2Engine; } } }
// SM3
package com.lzy.util;
import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; /** * 国密SM3算法 */ public class SM3 { private static final String ENCODING = "UTF-8"; static { Security.addProvider(new BouncyCastleProvider()); } /** * 计算数据摘要, * 源数据发生变化时,计算得到的摘要值不同,一般用于数据完整性校验; * * @param srcData * @return */ public static byte[] hash(byte[] srcData) { SM3Digest digest = new SM3Digest(); //update the message digest with a single byte. digest.update(srcData, 0, srcData.length); byte[] hash = new byte[digest.getDigestSize()]; //close the digest, producing the final digest value. digest.doFinal(hash, 0); return hash; } /** * 通过密钥进行加密 * @explain 指定密钥进行加密 * @param key 密钥 * @param srcData 被加密的byte数组 * @return */ public static byte[] hmac(byte[] key, byte[] srcData) { KeyParameter keyParameter = new KeyParameter(key); SM3Digest digest = new SM3Digest(); HMac mac = new HMac(digest); mac.init(keyParameter); mac.update(srcData, 0, srcData.length); byte[] result = new byte[mac.getMacSize()]; mac.doFinal(result, 0); return result; } public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException { String data = "测试国密算法。。。"; // 计算数据摘要 byte[] hash = hash(data.getBytes(StandardCharsets.UTF_8)); String s = ByteUtils.toHexString(hash); System.out.println(s); byte[] key = SM4.generateKey(); byte[] hmac = hmac(key, data.getBytes(StandardCharsets.UTF_8)); System.out.println(ByteUtils.toHexString(hmac)); } } // Sm4 package com.lzy.cipher; import com.lzy.util.ByteUtils; import com.lzy.util.FileUtils; import com.lzy.util.Sm3Utils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.nio.charset.StandardCharsets; import java.security.*; /** * @Description SM2实现工具类 * @date 2021/11/24 17:10 */ public class Sm4Util { static { Security.addProvider(new BouncyCastleProvider()); } public static final String ALGORITHM_NAME = "SM4"; public static final String DEFAULT_KEY = "random_seed"; // 128-32位16进制;256-64位16进制 public static final int DEFAULT_KEY_SIZE = 128; public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException { return generateKey(DEFAULT_KEY, DEFAULT_KEY_SIZE); } public static byte[] generateKey(String seed) throws NoSuchAlgorithmException, NoSuchProviderException { return generateKey(seed, DEFAULT_KEY_SIZE); } public static byte[] generateKey(String seed, int keySize) throws NoSuchAlgorithmException, NoSuchProviderException { KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME); SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); if (null != seed && !"".equals(seed)) { random.setSeed(seed.getBytes()); } kg.init(keySize, random); return kg.generateKey().getEncoded(); } /** * @description 加密 */ public static byte[] encrypt(String algorithmName, byte[] key, byte[] iv, byte[] data) throws Exception { return sm4core(algorithmName, Cipher.ENCRYPT_MODE, key, iv, data); } /** * @description 解密 */ public static byte[] decrypt(String algorithmName, byte[] key, byte[] iv, byte[] data) throws Exception { return sm4core(algorithmName, Cipher.DECRYPT_MODE, key, iv, data); } private static byte[] sm4core(String algorithmName, int type, byte[] key, byte[] iv, byte[] data) throws Exception { Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME); if (algorithmName.contains("/ECB/")) { cipher.init(type, sm4Key); } else { IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); cipher.init(type, sm4Key, ivParameterSpec); } return cipher.doFinal(data); } public static void main(String[] args) throws Exception { // byte[] key = generateKey(); // System.out.println("key:" + new String(key)); // String iv = "1234567890aabcba"; // String plain = "testabc"; // // byte[] encrypt = encrypt("SM4/CBC/PKCS7PADDING", key, iv.getBytes(StandardCharsets.UTF_8), plain.getBytes()); // byte[] decrypt = decrypt("SM4/CBC/PKCS7PADDING", key, iv.getBytes(StandardCharsets.UTF_8), encrypt); // System.out.println(new String(decrypt).equals(plain)); // byte[] key = sm4ByFileEn(); // System.out.println(ByteUtils.byteArrToHexStr(key)); String key = ByteUtils.byteArrToHexStr(generateKey()); String iv = "1234567890aabcba"; String sourceFilePath = "D:\\workspace\\cipherTest\\plain.txt"; String enFilePath = "D:\\workspace\\cipherTest\\cipher.txt"; String deFilePath = "D:\\workspace\\cipherTest\\decrypt.txt"; // sm4ByFile(Cipher.ENCRYPT_MODE, sourceFilePath, enFilePath, key, iv); sm4ByFile(Cipher.DECRYPT_MODE, enFilePath, deFilePath, key, iv); // byte[] en = FileUtils.toByteArrayMapped(enFilePath); // byte[] decrypt = decrypt("SM4/CBC/PKCS7PADDING", ByteUtils.hexStrToByteArr(key), // iv.getBytes(StandardCharsets.UTF_8), en); // // byte[] pBytes = FileUtils.toByteArrayMapped(sourceFilePath); // byte[] pHash = Sm3Utils.hash(pBytes); // byte[] deBytes = FileUtils.toByteArrayMapped(deFilePath); // byte[] deHash = Sm3Utils.hash(decrypt); // // System.out.println(new String(pHash).equals(new String(deHash))); byte[] plain = FileUtils.toByteArrayMapped(sourceFilePath); byte[] encrypt = encrypt("SM4/CBC/PKCS7PADDING", ByteUtils.hexStrToByteArr(key), iv.getBytes(StandardCharsets.UTF_8), plain); FileUtils.byteToFile(enFilePath,encrypt); sm4ByFile(Cipher.DECRYPT_MODE, enFilePath, deFilePath, key, iv); byte[] de = FileUtils.toByteArrayMapped(deFilePath); byte[] hash = Sm3Utils.hash(plain); byte[] dec = Sm3Utils.hash(de); System.out.println(new String(hash).equals(new String(dec))); } private static void sm4ByFile(int type, String sourceFilePath, String destFilePath, String key, String iv) throws Exception { final String algorithmName = "SM4/CBC/PKCS7PADDING"; final String ALGORITHM_NAME = "SM4"; // 加密 File sourceFile = new File(sourceFilePath); File destFile = new File(destFilePath); if (!sourceFile.exists() && !sourceFile.isFile()) { throw new IllegalArgumentException("加密源文件不存在"); } if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); InputStream in = new FileInputStream(sourceFile); OutputStream out = new FileOutputStream(destFile); // init cipher Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); Key sm4Key = new SecretKeySpec(ByteUtils.hexStrToByteArr(key), ALGORITHM_NAME); if (algorithmName.contains("/ECB/")) { cipher.init(type, sm4Key); } else { IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); cipher.init(type, sm4Key, ivParameterSpec); } CipherOutputStream cout = new CipherOutputStream(out, cipher); byte[] cache = new byte[1024]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { cout.write(cache, 0, nRead); cout.flush(); } cout.close(); out.close(); in.close(); } private static byte[] sm4ByFileEn() throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException { String sourceFilePath = "D:\\workspace\\cipherTest\\plain.txt"; String cipherFilePath = "D:\\workspace\\cipherTest\\cipher.txt"; byte[] key = generateKey(); String iv = "1234567890aabcba"; String algorithmName = "SM4/CBC/PKCS7PADDING"; // 加密 File sourceFile = new File(sourceFilePath); File destFile = new File(cipherFilePath); if (!sourceFile.exists() && !sourceFile.isFile()) { throw new IllegalArgumentException("加密源文件不存在"); } if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); InputStream in = new FileInputStream(sourceFile); OutputStream out = new FileOutputStream(destFile); // init cipher Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME); if (algorithmName.contains("/ECB/")) { cipher.init(Cipher.ENCRYPT_MODE, sm4Key); } else { IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); cipher.init(Cipher.ENCRYPT_MODE, sm4Key, ivParameterSpec); } CipherOutputStream cout = new CipherOutputStream(out, cipher); byte[] cache = new byte[1024]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { cout.write(cache, 0, nRead); cout.flush(); } cout.close(); out.close(); in.close(); return key; } private static void sm4ByFileDe() throws Exception { String sourceFilePath = "D:\\workspace\\cipherTest\\cipher.txt"; String decryptFilePath = "D:\\workspace\\cipherTest\\decrypt.txt"; byte[] key = ByteUtils.hexStrToByteArr("ee970aad570e4d4ebc17f7a68e78689a"); String iv = "1234567890aabcba"; String algorithmName = "SM4/CBC/PKCS7PADDING"; // 加密 File sourceFile = new File(sourceFilePath); File destFile = new File(decryptFilePath); if (!sourceFile.exists() && !sourceFile.isFile()) { throw new IllegalArgumentException("加密源文件不存在"); } if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); InputStream in = new FileInputStream(sourceFile); OutputStream out = new FileOutputStream(destFile); // init cipher Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME); if (algorithmName.contains("/ECB/")) { cipher.init(Cipher.DECRYPT_MODE, sm4Key); } else { IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)); cipher.init(Cipher.DECRYPT_MODE, sm4Key, ivParameterSpec); } CipherOutputStream cout = new CipherOutputStream(out, cipher); byte[] cache = new byte[1024]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { cout.write(cache, 0, nRead); cout.flush(); } cout.close(); out.close(); in.close(); } }
// pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.9</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.lzy</groupId> <artifactId>kafka-practice</artifactId> <version>0.0.1-SNAPSHOT</version> <name>kafka-practice</name> <description>kafka-practice</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- obs依赖 --> <dependency> <groupId>com.huaweicloud</groupId> <artifactId>esdk-obs-java-bundle</artifactId> <version>[3.21.11,)</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.9.3</version> </dependency> <dependency> <groupId>com.squareup.okio</groupId> <artifactId>okio</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.13.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.0</version> </dependency> <!-- bouncycastle --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.58</version> </dependency> <!-- 国密算法工具-SmUtil --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15to18</artifactId> <version>1.66</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> </plugins> </build> </project>
// ByteUtils.java
package com.lzy.util; public class ByteUtils { /** * 将byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813 * @param byteArr * @return 转换后的字符串 * @throws Exception */ public static String byteArrToHexStr(byte[] byteArr) throws Exception { int iLen = byteArr.length; // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍 StringBuffer sb = new StringBuffer(iLen * 2); for (int i = 0; i < iLen; i++) { int intTmp = byteArr[i]; // 把负数转换为正数 while (intTmp < 0) { intTmp = intTmp + 256; } // 小于0F的数需要在前面补0 if (intTmp < 16) { sb.append("0"); } sb.append(Integer.toString(intTmp, 16)); } return sb.toString(); } /** * 将表示16进制值的字符串转换为byte数组 * @param hexStr 需要转换的字符串 * @return 转换后的byte数组 */ public static byte[] hexStrToByteArr(String hexStr) throws Exception { byte[] arrB = hexStr.getBytes(); int iLen = arrB.length; // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2 byte[] arrOut = new byte[iLen / 2]; for (int i = 0; i < iLen; i = i + 2) { String strTmp = new String(arrB, i, 2); arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16); } return arrOut; } }
// FileUtils.java
package com.lzy.util; import lombok.extern.slf4j.Slf4j; import java.io.*; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; // 参考连接: https://blog.csdn.net/jellyjiao2008/article/details/85335569 @Slf4j public class FileUtils { /** * <p>Title: getContent</p> * <p>Description:根据文件路径读取文件转出byte[] </p> * * @param filePath 文件路径 * @return 字节数组 * @throws IOException */ public static byte[] getContent(String filePath) throws IOException { File file = new File(filePath); long fileSize = file.length(); if (fileSize > Integer.MAX_VALUE) { log.info("file too big..."); return null; } FileInputStream fi = new FileInputStream(file); byte[] buffer = new byte[(int) fileSize]; int offset = 0; int numRead = 0; while (offset < buffer.length && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) { offset += numRead; } // 确保所有数据均被读取 if (offset != buffer.length) { throw new IOException("Could not completely read file " + file.getName()); } fi.close(); return buffer; } /** * <p>Title: toByteArray</p> * <p>Description: 传统的IO流方式</p> * * @param filename * @return * @throws IOException */ public static byte[] toByteArray(String filename) throws IOException { File file = new File(filename); if (!file.exists()) { throw new FileNotFoundException(filename); } try (ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) { int buf_size = 1024; byte[] buffer = new byte[buf_size]; int len = 0; while (-1 != (len = in.read(buffer, 0, buf_size))) { bos.write(buffer, 0, len); } return bos.toByteArray(); } catch (IOException e) { e.printStackTrace(); throw e; } } /** * <p>Title: toByteArrayMapped</p> * <p>Description: 读取大文件</p> * * @param filename 文件路径 * @return * @throws IOException */ public static byte[] toByteArrayMapped(String filename) throws IOException { try (RandomAccessFile rf = new RandomAccessFile(filename, "r"); FileChannel fc = rf.getChannel()) { MappedByteBuffer mappedByteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()).load(); log.info("{}", mappedByteBuffer.isLoaded()); byte[] result = new byte[(int) fc.size()]; if (mappedByteBuffer.remaining() > 0) { mappedByteBuffer.get(result, 0, mappedByteBuffer.remaining()); } return result; } catch (IOException e) { e.printStackTrace(); throw e; } } /** * 写出到文件 * @param filePath * @throws Exception */ public static void byteToFile(String filePath, byte[] data) throws Exception { Path path = Paths.get(filePath); // 读取、写入字节数组 // byte[] data = Files.readAllBytes(path); Files.write(path, data); /* // 读取、写入字符 Since:Java11 // 默认使用UTF-8编码读取: String content1 = Files.readString(path); // 可指定编码: String content2 = Files.readString(path, StandardCharsets.UTF_8); // 按行读取并返回每行内容: List<String> lines = Files.readAllLines(path); // 写入文本并指定编码: Since:Java11 Files.writeString(path, "文本内容...", StandardCharsets.UTF_8); // 按行写入文本: Files.write(path, lines); */ } }