Java 读写 ini ( 调用 Windows Api )

市面上读取 ini 的包都是 读取整个文件到内存中,再获取和修改值,
最后自己再调用保存文件, 这种方式在读取大文件的时候 非常的不友好.

windows api 中有现成的高效方法

安装 jna-platform
(里面封装了各个系统的 api ,直接用就行. 不用再手动写固定的函数定义)

  • jna-platform 是官方基于jna 封装好的 系统 API,
  • jna 是调用自己写的 DLL

pom.xml

<dependency><groupId>net.java.dev.jna</groupId><artifactId>jna-platform</artifactId><version>5.14.0</version>
</dependency>

IniUtil.java

package org.example.myapp.utils;import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Win32Exception;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.W32APIOptions;import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;public class IniUtil {public static String getPrivateProfileString(final String lpAppName,final String lpKeyName, final String lpDefault,final String lpFileName) {final char buffer[] = new char[1024];Kernel32.INSTANCE.GetPrivateProfileString(lpAppName, lpKeyName,lpDefault, buffer, new WinDef.DWORD(buffer.length), lpFileName);return Native.toString(buffer);}public static void writePrivateProfileString(final String appName, final String keyName, final String string, final String fileName) {if (!Kernel32.INSTANCE.WritePrivateProfileString(appName, keyName, string, fileName))throw new Win32Exception(Kernel32.INSTANCE.GetLastError());}public static int getPrivateProfileInt(final String appName,final String keyName, final int defaultValue, final String fileName) {return Kernel32.INSTANCE.GetPrivateProfileInt(appName, keyName,defaultValue, fileName);}public static String[] getPrivateProfileSection(final String appName, final String fileName) {final char buffer[] = new char[32768];// Maximum INI file size according to MSDN (http://support.microsoft.com/kb/78346)if (Kernel32.INSTANCE.GetPrivateProfileSection(appName, buffer, new WinDef.DWORD(buffer.length), fileName).intValue() == 0) {throw new Win32Exception(Kernel32.INSTANCE.GetLastError());}return new String(buffer).split("\0");}public static String[] getPrivateProfileSectionNames(final String fileName) {final char buffer[] = new char[65536]; // Maximum INI file size according to MSDN (http://support.microsoft.com/kb/78346)if (Kernel32.INSTANCE.GetPrivateProfileSectionNames(buffer, new WinDef.DWORD(buffer.length), fileName).intValue() == 0) {throw new Win32Exception(Kernel32.INSTANCE.GetLastError());}return new String(buffer).split("\0");}public static void writePrivateProfileSection(final String appName, final String[] strings, final String fileName) {final StringBuilder buffer = new StringBuilder();for (final String string : strings)buffer.append(string).append('\0');buffer.append('\0');if (!Kernel32.INSTANCE.WritePrivateProfileSection(appName, buffer.toString(), fileName)) {throw new Win32Exception(Kernel32.INSTANCE.GetLastError());}}public interface MyKernel32 extends Library {/***  用来写入 中文 (**  @desc*  jna-platform 5.14 源码中*  Map<String, Object> DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;`*  在我的电脑上是 UNICODE_OPTIONS, 会导致 中文乱码 (编码是 gbk, 文件编码是 UTF-8))*  所以手动写这个函数定义 指定为 ASCII_OPTIONS (文件编码是 UTF-8, 中文正常显示 )*/MyKernel32 INSTANCE = Native.load("kernel32", MyKernel32.class, W32APIOptions.ASCII_OPTIONS);boolean WritePrivateProfileString(String lpAppName, String lpKeyName,String lpString, String lpFileName);}String _filePath;public IniUtil(String filePath) {_filePath = filePath;}public String readString(String sectionName, String keyName) {return getPrivateProfileString(sectionName, keyName, "", _filePath);}public String readString(String sectionName, String keyName, String defaultValue) {return getPrivateProfileString(sectionName, keyName, defaultValue, _filePath);}public Integer readInt(String sectionName, String keyName) {return getPrivateProfileInt(sectionName, keyName, 0, _filePath);}public Integer readInt(String sectionName, String keyName, Integer defaultValue) {return getPrivateProfileInt(sectionName, keyName, defaultValue, _filePath);}/*** 获取 sectionName 下所有的 keyName** @param sectionName* @return*/public ArrayList<String> readKeysBySectionName(String sectionName) {ArrayList<String> result = new ArrayList<>();final char buffer[] = new char[65536];WinDef.DWORD res = Kernel32.INSTANCE.GetPrivateProfileString(sectionName, null,null, buffer, new WinDef.DWORD(buffer.length), _filePath);int len = res.intValue();int j = 0;for (int i = 0; i < len; i++) {if (buffer[i] == 0) {String str = new String(buffer, j, i - j);result.add(str);j = i + 1;}}return result;}public ArrayList<String> readAllSectionNames() {ArrayList<String> result = new ArrayList<>();final char buffer[] = new char[65536];WinDef.DWORD res = Kernel32.INSTANCE.GetPrivateProfileString(null, null,null, buffer, new WinDef.DWORD(buffer.length), _filePath);int len = res.intValue();int j = 0;for (int i = 0; i < len; i++) {if (buffer[i] == 0) {String str = new String(buffer, j, i - j);result.add(str);j = i + 1;}}return result;}/*** 读取所有数据 ( !! 大文件慎用,会很慢, 小文件随意用)** @return*/public Dictionary<String, Dictionary<String, String>> readAllData() {Dictionary<String, Dictionary<String, String>> resultDictionary = new Hashtable<>();ArrayList<String> allSectionList = readAllSectionNames();for (String item : allSectionList) {ArrayList<String> allKeyList = readKeysBySectionName(item);Dictionary<String, String> dataDictionary = new Hashtable<>();for (String child : allKeyList) {String value = readString(item, child);dataDictionary.put(child, value);}resultDictionary.put(item, dataDictionary);}return resultDictionary;}/*** 新增 / 修改  (如果存在则修改,否则添加,没有文件会创建)** @param sectionName* @param keyName* @param value*/public void writeString(String sectionName, String keyName, String value) {// NOTE: jna-platform 封装的方法写入中文, 会乱码, 所以调用自己写的MyKernel32.INSTANCE.WritePrivateProfileString(sectionName, keyName, value, _filePath);}/*** 删除指定的 Section** @param sectionName*/public void deleteSection(String sectionName) {writePrivateProfileString(sectionName, null, null, _filePath);}/*** 删除所有内容*/public void deleteAllSection() {writePrivateProfileString(null, null, null, _filePath);}/*** 删除一个 key** @param sectionName* @param keyName*/public void deleteKey(String sectionName, String keyName) {writePrivateProfileString(sectionName, keyName, null, _filePath);}
}

测试一下

注入到 spring boot 中

package org.example.myapp.config;import org.example.myapp.utils.IniUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class IniConf {@Beanpublic IniUtil iniUtil() {String fileName = "D:\\Desktop\\demo.ini";return new IniUtil(fileName);}
}

调用

@Autowired
public IniUtil ini;@GetMapping("/test")
public Integer test()  {// 测试自己封装的方法String s = ini.readString("colors", "background");    System.out.println(s);ini.writeString("General","test3","测试数据");//ini.deleteKey("General","test3");// 测试静态方法Integer ss= IniUtil.getPrivateProfileInt("colors","name",0,"D:\\Desktop\\demo.ini");return ss;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JPA常见异常 JPA可能抛出的异常

1、EntityNotFoundException&#xff08;实体不存在异常&#xff09;: 通过 JPA 查找一个不存在的实体。 2、NonUniqueResultException&#xff08;非唯一结果异常&#xff09;&#xff1a; 查询返回了多个结果&#xff0c;但期望只有一个结果。 3、TransactionRequiredExcep…

AutoSAR(基础入门篇)13.1-EB Tresos使用初探

目录 一、新建工程 二、添加和删除模块 三、界面 四、代码生成 1、直接生成代码

Mac 以SH脚本安装Arthas

SH脚本安装Aethas curl -L https://alibaba.github.io/arthas/install.sh | sh安装脚本说明 示例源文件&#xff1a; #! /bin/bash# temp file of as.sh TEMP_ARTHAS_FILE"./as.sh.$$"# target file of as.sh TARGET_ARTHAS_FILE"./as.sh"# update timeo…

微服务中的Feign:优雅实现远程调用的秘密武器(一)

本系列文章简介&#xff1a; 本系列文章将深入探讨Feign的特点、原理以及在微服务中的应用场景&#xff0c;帮助读者更好地理解和使用这个优秀的远程调用工具。无论您是初学者还是有经验的开发人员&#xff0c;本文都将为您揭示Feign的秘密&#xff0c;并带您一起走进微服务的世…

人类与机器的不同交流特点

对人类而言&#xff0c;事实是用来交流的&#xff0c;价值是用来自我交流的。事实是用来交流的&#xff0c;是通过提供准确、可证实的信息来传递和共享知识的。事实具有客观性&#xff0c;不受个人主观意见的影响。通过分享事实&#xff0c;人们可以更好地理解世界和彼此&#…

Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius,Kotlin

Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius&#xff0c;Kotlin 这里 Android挖取原图中心区域RectF(并框线标记)放大到ImageView宽高&#xff0c;Kotlin-CSDN博客 实现的是把原图中心区域的一片小图挖取出来放大放到下面的ImageView里面…

if语句用法

if语句是单条件分支语句 定义&#xff1a;根据一个条件来控制程序执行流程(如图3.2)。 语法格式&#xff1a; if&#xff08;表达式&#xff09;{ 若干语句 } ★注意★&#xff1a; ① 表达式的值必须是boolean 型&#xff1b; ② 不能用0代表false&#xff1b;用1代表 true&am…

德人合科技 | —数据泄露可能会对公司造成哪些影响?

数据泄露可能会对公司造成多方面的影响&#xff0c;以下是一些可能的影响&#xff1a; 财务损失&#xff1a;数据泄露可能导致公司遭受财务损失。攻击者可能会盗取公司的敏感信息&#xff0c;如客户信息、银行账户信息、商业机密等&#xff0c;并利用这些信息进行欺诈、盗窃等非…

「优选算法刷题」:验证栈序列

一、题目 给定 pushed 和 popped 两个序列&#xff0c;每个序列中的 值都不重复&#xff0c;只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时&#xff0c;返回 true&#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a…

本地maven库缓存导入私库

为了加速编译代码&#xff0c;想将本地maven缓存导入内网私库使用。 脚本网上搜的 #!/bin/bash # copy and run this script to the root of the repository directory containing files # this script attempts to exclude uploading itself explicitly so the script name …

高效备考2024年AMC10:吃透2000-2023年1250道AMC10真题

距离2024年AMC10的比赛只有8个月多一点的时间了&#xff0c;如何备考AMC10美国数学竞赛最有效&#xff1f;参加AMC10竞赛是否一定要参加机构的培训班&#xff1f;吃透历年真题是有效的自学、了解AMC10和备考策略之一。事实上&#xff0c;网络上有很多关于AMC10的学习资源&#…

Github 2024-03-02 开源项目日报Top9

根据Github Trendings的统计&#xff0c;今日(2024-03-02统计)共有9个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量非开发语言项目2Rust项目1JavaScript项目1Shell项目1C项目1TypeScript项目1C#项目1Python项目1 任天堂Switch模…

InnoDB备份与恢复篇(4)-InnoDB的故障恢复与日志分析

在MySQL数据库中&#xff0c;InnoDB是一种非常常用的存储引擎。它提供了高性能和可靠性&#xff0c;同时也具备故障恢复和日志分析的能力。本文将介绍InnoDB的故障恢复机制和日志分析方法。 一、故障恢复机制 事务和写日志&#xff1a; 在InnoDB中&#xff0c;所有的数据操作都…

NIST网络安全框架2.0版发布:十年磨一剑,安全再升级

美国国家标准与技术研究院(NIST)近日发布了网络安全框架(CSF)的2.0正式版本&#xff0c;这是2014年该框架发布后十年来首次重大更新。新框架版本极大扩展了适用范围&#xff0c;重点关注治理和供应链问题&#xff0c;并提供了丰富的资源以加速框架实施。 NIST正式发布的网络安全…

决定西弗吉尼亚州地区版图的关键历史事件

决定西弗吉尼亚州地区版图的关键历史事件&#xff1a; 1. 内部分裂与美国内战&#xff1a; - 在1861年美国内战爆发时&#xff0c;弗吉尼亚州作为南方邦联的一员宣布退出美利坚合众国。然而&#xff0c;弗吉尼亚州西部的一些县由于经济结构&#xff08;主要是农业非依赖奴隶制…

使用Python进行Sentinel-2 图像聚类

聚类或无监督分类是根据统计相似性将图像的像素值分组或聚合到一定数量的自然类(组)的过程。在本教程中,我们将使用rasterio进行sentinel-2图像处理,并使用功能强大的完整scikit-learn python 包在jupyter Notebook中进行聚类。 Scikit-learn是一个用于 Python 编程语言的…

Redis 存储原理和数据模型

redis 是不是单线程 redis 单线程指的是命令处理在一个单线程中。主线程 redis-server&#xff1a;命令处理、网络事件的监听。 辅助线程 bio_close_file&#xff1a;异步关闭大文件。bio_aof_fsync&#xff1a;异步 aof 刷盘。bio_lazy_free&#xff1a;异步清理大块内存。io_…

一种基于三角剖分划分白区范围的白平衡算法

常规的白平衡算法中,一般会通过标准色温的R/G-B/G建议色温坐标系,然后在该坐标系中设定白区范围,对落入到白区范围的R/G/B进行加权统计处理,输出给到软件进行白平衡的增益计算。 所介绍的这篇专利利用三角剖分的算法,在划定的白区范围内,利用各个标准色温光源下所标定的白…

STM32------分析GPIO寄存器

一、初始LED原理图 共阴极led LED发光二极管&#xff0c;需要有电流通过才能点亮&#xff0c;当有电压差就会产生电流 二极管两端的电压差超过2.7v就会有电流通过 电阻的作用 由于公式IV/R 不加电阻容易造成瞬间电流无穷大 发光二极管工作电流为10-20MA 3.3v / 1kΩ 3.…

C#中什么是非托管代码?托管代码和非托管代码有什么区别

在C#中&#xff0c;托管代码和非托管代码是两种不同类型的代码&#xff0c;它们在内存管理和执行环境上有所不同。 托管代码&#xff08;Managed Code&#xff09;&#xff1a; 托管代码是由.NET运行时&#xff08;CLR&#xff0c;Common Language Runtime&#xff09;管理和执…