滚雪球学Java(65-5):面对Properties的各种坑,你需要知道的Java小技巧

在这里插入图片描述

  咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~

在这里插入图片描述


🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

文章目录

  • 前言
  • 摘要
  • Properties讲解
    • 简介
    • 源代码解析
      • 读取`Properties`乱码问题
      • Properties中键值对含有特殊字符
      • 写入Properties文件
    • 应用场景案例
      • 读取web.xml文件
      • 写入Properties到数据库
    • 优缺点分析
      • 优点
      • 缺点
    • 类代码方法介绍
      • Properties类方法介绍
      • InputStream类方法介绍
      • OutputStream类方法介绍
      • PreparedStatement类方法介绍
    • 测试用例
      • 测试代码演示
      • 测试结果
      • 测试代码分析
    • 小结
  • 总结
    • 附录源码
  • ☀️建议/推荐你
  • 📣关于我

前言

  在Java日常开发中,Properties是一种常用的键值对存储方式,用于配置文件和环境变量等常见场景。但是,在使用Properties时,经常会遇到各种坑,例如读写乱码、键值对中含有特殊字符等问题。本文将通过代码示例和场景案例,介绍如何避免这些问题,让你在使用Properties时更加得心应手。

摘要

  • Properties是Java中常用的键值对存储方式,用于配置文件和环境变量等场景。
  • 在使用Properties时,需要注意读写乱码、键值对中特殊字符的处理等问题。
  • 通过代码示例和场景案例,本文介绍了如何避免这些问题,让你在使用Properties时更加得心应手。

Properties讲解

简介

  Properties是Java中常用的键值对存储方式,其存储方式和Map类似。Properties可以通过load()方法从文件中读取内容,也可以直接通过setProperty()方法添加键值对。Properties一般用于存储配置文件和环境变量等常见场景,其优点在于格式简单、易于阅读和修改。

下面是一个简单的Properties示例:

#配置文件示例
ip=192.168.1.1
port=8080
username=admin
password=123456

读取配置文件内容的代码如下:

Properties props = new Properties();
InputStream in = new BufferedInputStream(new FileInputStream("config.properties"));
props.load(in);
in.close();String ip = props.getProperty("ip");
int port = Integer.parseInt(props.getProperty("port"));
String username = props.getProperty("username");
String password = props.getProperty("password");

源代码解析

读取Properties乱码问题

在读取Properties文件时,有可能出现乱码问题。这是因为Properties默认使用ISO-8859-1编码方式,如果我们的文件是其他编码方式,就会出现乱码。

在这里插入图片描述

解决方法如下:

Properties props = new Properties();
InputStream in = new FileInputStream("config.properties");
props.load(new InputStreamReader(in, "UTF-8"));
in.close();String ip = props.getProperty("ip");
int port = Integer.parseInt(props.getProperty("port"));
String username = props.getProperty("username");
String password = props.getProperty("password");

  在读取Properties文件时,使用InputStreamReader指定文件的编码方式为UTF-8即可。

拓展:

  上述代码使用了 Java 中的 Properties类来读取一个名为 “config.properties” 的文件。该文件中包含了用于连接远程服务器的 IP 地址,端口,用户名和密码等信息。

  首先创建一个 Properties对象,并加载 config.properties 文件。通过 FileInputStream 类和 InputStreamReader 类来读取该文件,并且使用 UTF-8 编码解析文件内容。最后关闭输入流。

  然后,从读取的 Properties 对象中获取 IP 地址、端口、用户名和密码等属性值,并将它们分别存储在字符串和整数类型的变量中。

  通过这种方式,就可以方便地读取并使用 config.properties 文件中的配置信息。

Properties中键值对含有特殊字符

  当键值对中含有特殊字符时,例如空格、冒号等,需要进行特殊处理。

下面是两种方法:

Properties props = new Properties();
InputStream in = new FileInputStream("config.properties");
props.load(in);
in.close();String ip = props.getProperty("ip");
String port = props.getProperty("port");
String username = props.getProperty("username");
String password = props.getProperty("password");//方法一
ip = ip.replaceAll("\\s+", "");
port = port.replaceAll(":","");
username = username.replaceAll("\"","");
password = password.replaceAll("\'","");//方法二
ip = ip.replace(" ", "");
port = port.replace(":", "");
username = username.replace("\"", "");
password = password.replace("\'", "");

  方法一使用正则表达式replaceAll()方法,将特殊字符替换为空字符串;方法二使用replace()方法,将特殊字符替换为普通字符。

拓展:

  该代码是读取一个配置文件(config.properties),并且获取其中的IP地址、端口号、用户名和密码。然后使用两种方法将获取的值进行处理。

  方法一使用了正则表达式,将IP地址中的空格、端口号中的冒号以及用户名和密码中的引号删除。

  方法二则直接使用了字符串的replace()方法,将空格、冒号和引号替换为""(空字符串)。

  这些处理的目的都是为了获得一个干净、规范的字符串,以便后续的操作。

写入Properties文件

写入Properties文件有两种方法,一种是使用OutputStream写入,另一种是使用Properties.store()方法写入。

//方法一
OutputStream out = new FileOutputStream("config.properties");
props.store(out, "update");
out.close();//方法二
FileOutputStream output = new FileOutputStream("config.properties");
props.store(new OutputStreamWriter(output, "utf-8"), "update");
output.close();

  在写入Properties文件时,需要注意文件的编码方式,一般使用UTF-8。

拓展:

  以上代码是在Java中操作properties文件的示例代码,其中props代表一个Properties对象,它包含了一些配置信息。在这段代码中,通过将Properties对象写入OutputStream或OutputStreamWriter,将其保存到config.properties文件中。

  方法一使用了FileOutputStream,直接将Properties对象写入输出流中,使用store()方法进行保存。该方法使用了默认的ISO-8859-1编码格式,因此如果文件中含有中文等特殊字符可能会出现乱码。最后使用close()方法关闭输出流。

  方法二使用了更加灵活的方式,通过构造OutputStreamWriter指定编码格式,解决了乱码的问题。同样使用store()方法保存Properties对象,最后也要使用close()方法关闭输出流。

  总的来说,这两种方法的核心是使用Properties类提供的store()方法将Properties对象保存到文件中。但方法二相较于方法一更加灵活,能够解决编码问题。

应用场景案例

读取web.xml文件

  在web项目中,我们需要读取web.xml文件中的配置信息,例如servletlistener等配置信息。下面是一个读取web.xml文件中的servlet配置信息的示例代码:

public class ReadWebXml {public static void main(String[] args) throws Exception {Properties props = new Properties();InputStream in = new FileInputStream("web.xml");props.loadFromXML(in);in.close();Enumeration<?> en = props.propertyNames();while (en.hasMoreElements()) {String key = (String) en.nextElement();if (key.contains("servlet-name")) {String servletName = props.getProperty(key);String servletClass = props.getProperty(key.replace("name", "class"));System.out.println(servletName + " " + servletClass);}}}
}

  代码中读取web.xml文件时,使用loadFromXML()方法,读取XML格式的配置文件,具体读取方式和Properties相同。

写入Properties到数据库

  在Java中,我们经常将配置信息存储在数据库中,下面是一个将Properties写入MySQL数据库的示例代码:

public class WritePropertiesToDB {public static void main(String[] args) throws SQLException, ClassNotFoundException {Properties props = new Properties();props.setProperty("ip", "127.0.0.1");props.setProperty("port", "3306");props.setProperty("username", "root");props.setProperty("password", "123456");Class.forName("com.mysql.jdbc.Driver");Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname", "root", "123456");PreparedStatement ps = conn.prepareStatement("insert into config values(?,?,?,?)");Enumeration<?> en = props.propertyNames();int i = 1;while (en.hasMoreElements()) {String key = (String) en.nextElement();ps.setInt(1, i++);ps.setString(2, key);ps.setString(3, props.getProperty(key));ps.setDate(4, new Date(System.currentTimeMillis()));ps.executeUpdate();}ps.close();conn.close();}
}

  代码中,首先创建一个Properties对象,将配置信息存储在对象中。然后,使用JDBC连接MySQL数据库,将Properties中的键值对写入到数据库中。

优缺点分析

优点

  • 简单易用:Properties存储方式简单,易于阅读和修改。
  • 常用场景:Properties常用于存储配置文件和环境变量等常见场景。
  • 方便读写:Properties可以通过load()方法从文件中读取内容,也可以直接通过setProperty()方法添加键值对。

缺点

  • 存储方式有限:Properties只能存储字符串类型的键值对,无法存储其他类型的数据。
  • 不支持多线程:Properties不是线程安全的,不支持多线程操作,需要加锁保证安全。

类代码方法介绍

Properties类方法介绍

  • load(InputStream in):从输入流中读取属性列表(键和元素对)。
  • loadFromXML(InputStream in):从输入流中读取XML格式的属性列表(键和元素对)。
  • getProperty(String key):用指定的键在此属性列表中搜索属性。
  • setProperty(String key, String value):将指定的键值对写入到Properties中。
  • store(OutputStream out, String comments):将Properties写入到输出流中;comments为注释信息。
  • storeToXML(OutputStream os, String comment):将Properties写入到XML格式的输出流中;comment为注释信息。

InputStream类方法介绍

  • FileInputStream(String name):创建文件输入流。
  • BufferedInputStream(InputStream in):创建一个新的缓冲输入流,以将指定的输入流缓冲。
  • close():关闭此输入流并释放与该流关联的所有系统资源。

OutputStream类方法介绍

  • FileOutputStream(String name):创建文件输出流。
  • close():将此文件输出流关闭。在关闭流之前,将刷新此流。

PreparedStatement类方法介绍

  • executeUpdate():执行给定的SQL语句,该语句可能为INSERT、UPDATE或DELETE语句;或者不返回任何内容的SQL语句,如SQL DDL语句。

测试用例

  在编写代码时,为了避免出现错误,我们需要编写相应的测试用例。下面是一个测试文件读写的示例代码:

测试代码演示

package com.demo.javase.day65_5;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;/*** Properties示例演示** @Author bug菌* @Date 2023-11-06 16:53*/
public class PropertiesTest {public static void main(String[] args) throws IOException {testReadProperties();testWriteProperties();}// 测试读取Properties文件public static void testReadProperties() throws IOException {Properties props = new Properties();InputStream in = new FileInputStream("config/config.properties");props.load(new InputStreamReader(in, StandardCharsets.UTF_8));in.close();String ip = props.getProperty("ip");int port = Integer.parseInt(props.getProperty("port"));String username = props.getProperty("username");String password = props.getProperty("password");System.out.println("ip: " + ip);System.out.println("port: " + port);System.out.println("username: " + username);System.out.println("password: " + password);}// 测试写入Properties文件public static void testWriteProperties() throws IOException {Properties props = new Properties();props.setProperty("ip", "127.0.0.1");props.setProperty("port", "8080");props.setProperty("username", "admin");props.setProperty("password", "123456");OutputStream out = new FileOutputStream("config/newConfig.properties");props.store(new OutputStreamWriter(out, StandardCharsets.UTF_8), "New Config");out.close();}
}

测试结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

测试结果如下:

ip: 192.168.1.1
port: 8080
username: admin
password: 123456

  可以看出,读取Properties文件没有出现乱码问题;同时,写入Properties文件也成功了。

实际运行截图如下:

在这里插入图片描述

  然后我们来看newConfig.properties 文件,也成功被写入了指定的内容。

在这里插入图片描述

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。

  该代码主要演示了如何使用Java中的Properties类读取和写入Properties文件。

  在testReadProperties方法中,首先创建一个Properties实例,并使用FileInputStream打开一个配置文件。然后,通过Properties.load方法从InputStream中读取属性值,并使用getProperty方法获取属性值。最后将获取到的属性值打印出来。

  在testWriteProperties方法中,同样创建一个Properties实例,并使用setProperty方法设置属性值。然后,使用FileOutputStream打开一个新的文件,通过Properties.store方法将属性值写入OutputStream中,并指定文件编码和文件注释。最后关闭文件输出流。

小结

  本文介绍了在使用Properties时需要注意的问题,例如读写乱码、键值对含有特殊字符等。我们可以通过代码示例和场景案例来更好地理解和掌握Properties的使用方法。使用Properties可以很方便地存储和读取配置信息,同时也需要注意线程安全和存储类型的限制等问题。

总结

  本文介绍了Java中常用的键值对存储方式——Properties,主要包括读取Properties时的乱码问题、处理键值对含有特殊字符的方法、写入Properties文件到数据库的示例代码等。在使用Properties时,需要注意存储类型的限制和线程安全等问题。本文还提供了测试用例和类方法介绍,帮助读者更加深入了解和掌握Properties的使用方法。

  … …

  好啦,这期的内容就基本接近尾声啦,若你想学习更多,你可以看看专栏的导读篇《「滚雪球学Java」教程导航帖》,本专栏致力打造最硬核 Java 零基础系列学习内容,🚀打造全网精品硬核专栏,带你直线超车;欢迎大家订阅持续学习。功不唐捐,久久为功!

「赠人玫瑰,手留余香」,咱们下期拜拜~~

附录源码

  如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。

☀️建议/推荐你

  无论你是计算机专业的学生,还是对编程感兴趣的跨专业小白,都建议直接入手「滚雪球学Java」专栏;该专栏不仅免费,bug菌还郑重承诺,只要你学习此专栏,均能入门并理解Java SE,以全网最快速掌握Java语言,每章节源码均同步「Gitee」,你真值得拥有;学习就像滚雪球一样,越滚越大,带你指数级提升。

码字不易,如果这篇文章对你有所帮助,帮忙给bugj菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。

同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!

📣关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 20w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。


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

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

相关文章

C++初学者指南-5.标准库(第二部分)--移除元素算法

C初学者指南-5.标准库(第二部分)–移除元素算法 文章目录 C初学者指南-5.标准库(第二部分)--移除元素算法remove / remove_ifremove_copy / remove_copy_ifunique / unique_copyerase / erase_if相关内容 不熟悉 C 的标准库算法&#xff1f; ⇒ 简介 remove / remove…

【解决error】安装torch 1.1.0

第一步 当云服务器上没有指定版本的torch可以选择 先确定指定torch符合的python版本号 例如这里&#xff0c;我需要安装torch1.1.0&#xff0c;所以需要python>3.6 且 python<3.7 根据python版本&#xff0c;确定服务器安装torch的版本配置 第二步 新建conda虚拟环境…

iPhone苹果密码解锁工具专业版_不限制电脑

iPhone苹果密码解锁工具专业版_不限制电脑 Aiseesoft iPhone Unlocker&#xff1a;轻松解锁iPhone。功能强大&#xff1a;一键移除4位、6位密码、Touch ID和Face ID。 隐私保护&#xff1a;创建密码&#xff0c;安全无忧。数据提醒&#xff1a;解锁时&#xff0c;注意数据和设…

docker部署可执行的jar

1.将项目打包&#xff0c;上传到服务器的指定目录 2.在该目录下创建Dockerfile文件 3.Dockerfile写入如下指令 # 基于哪个镜像 FROM java:8 # 拷贝文件到容器&#xff0c;也可以直接写成ADD xxxxx.jar /app.jar ADD springboot-file-0.0.1.jar file.jar RUN bash -c touch /…

用TypeScript完成的贪吃蛇小游戏

食物类Fod // 定义 class Food {// 定义一个属性表示食物所对应的元素element:HTMLElement;constructor(){//加个&#xff01;表示不能为空,非空断言操作符 //获取页面中的food元素并将其赋值给element this.elementdocument.getElementById(food)!;}// 定义一个获取食物x轴坐…

(六)activiti-modeler 设计器属性编辑弹窗bug修复

BUG重现 在使用流程设计器时&#xff0c;经常碰到弹窗不小心关闭&#xff0c;比如不小心点击了灰色背景上&#xff0c;此时BUG就出现了。弹窗被关闭了&#xff0c;分配用户属性被置空了&#xff0c;以前有数据也被清空了&#xff0c;还无法再次点击弹窗编辑。 不仅仅是分配用…

【Vue3】组件通信之v-model

【Vue3】组件通信之v-model 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的…

LDR6020快充线,科技与便捷的新宠

在快节奏的现代生活中&#xff0c;充电效率成为了我们不可忽视的一个重要因素。随着智能手机、平板电脑等电子设备的普及&#xff0c;快充线以其独特的优势逐渐成为充电设备市场的新宠。 快充线&#xff0c;相比于传统的普通充电线&#xff0c;快充线在充电速度上有着显著的提升…

五、一个quad同时支持pcie和sfp两种高速接口的ref时钟配置

项目描述 上位机将截图数据通过 XDMA 写入到 FPGA 侧的 DDR 内存区域 1 中通过 axi_lite 接口给 axi_read_start 信号&#xff0c;通知 AXI_read 模块启动读取数据&#xff0c;然后通过 GTP TX 模块发送出去。经过光纤回环&#xff0c;GTP RX 端接收到数据&#xff0c;送给 AX…

微分方程的数值解法——Runge-Kutta (RK4)

Runge-Kutta (RK4)   The Runge-Kutta (RK4) methods are used to solve the solution of the non-liner ordinary differential equation. Here, we will simply summary this method.   Assume the Intial Value Piont (IVP) is satisfied: y ′ f ( t , y ) , y ( t 0 )…

python-查找元素3(赛氪OJ)

[题目描述] 有n个不同的数&#xff0c;从小到大排成一列。现在告诉你其中的一个数x&#xff0c;x不一定是原先数列中的数。你需要输出最后一个<x的数在此数组中的下标。输入&#xff1a; 输入共两行第一行为两个整数n、x。第二行为n个整数&#xff0c;代表a[i]。输出&#x…

椭圆曲线加法运算

1. 定义 椭圆曲线 (Elliptic Curve) 不是函数&#xff0c;而是一条平面曲线&#xff0c;其方程是定义如下&#xff1a; y 2 x 3 a x b y^2x^3axb y2x3axb 其中&#xff0c;判别式 Δ − 16 ( 4 a 3 27 b 2 ) ≠ 0 \Delta -16(4a^327b^2)\neq 0 Δ−16(4a327b2)0。判别…

Java 并发编程:一文了解 synchronized 的使用

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 027 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

keil编译报错error:#8:missing closing quote 处理

MDK5采用UTF-8&#xff0c;提示很多个这样的error:#8&#xff1a;missing closing quote 的错误信息。提供以下几种方式解决&#xff1a; 在KEIL中Options for Target Flash -> C/C -> Misc Controls添加“--localeenglish”。

49 序列解包的多种形式和用法

序列解包&#xff08;Sequence Unpacking&#xff09;是 Python 中非常重要和常用的一个功能&#xff0c;可以使用非常简洁的形式完成复杂的功能&#xff0c;提高了代码的可读性&#xff0c;减少了程序员的代码输入量。 x, y, z 1, 2, 3 # 多个变量同时赋值 v_tuple (False…

【课程系列07】某乎AI大模型全栈工程师-第7期

网盘链接 链接&#xff1a;百度网盘 请输入提取码 --来自百度网盘超级会员v6的分享 课程目标 学习完毕咱们可以收获什么种能力&#xff1a; 1、传统前端 后端 数据分析 产品 绘图 算法工程等工作&#xff0c;一个人都可以实现&#xff0c;实现超级个体的能力 2、可以解决…

【C语言】Top K问题【建小堆】

前言 TopK问题&#xff1a;从n个数中&#xff0c;找出最大&#xff08;或最小&#xff09;的前k个数。 在我们生活中&#xff0c;经常会遇到TopK问题 比如外卖的必吃榜&#xff1b;成单的前K名&#xff1b;各种数据的最值筛选 问题分析 显然想开出40G的空间是不现实的&#…

基于STM32的温湿度监控系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码主循环代码应用场景 家居环境监控工业环境监控常见问题及解决方案 常见问题解决方案结论 1. 引言 在智能家居和工业自动化中&#xff0c;温湿度监控系统是一个非常重要的组成部分…

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址 可以看到里面大致有三种token&#xff0c;一个是服务商的token&#xff0c;一个是企业授权token&#xff0c;还有一个是应用的token 这里面主要有下面几个参数 首先是服务商的 corpid 和 provider_secret &#xff0c;这个可…

使用GCC编译Notepad++的插件

Notepad的本体1是支持使用MSVC和GCC编译的2&#xff0c;但是Notepad插件的官方文档3里却只给出了MSVC的编译指南4。 网上也没有找到相关的讨论&#xff0c;所以我尝试在 Windows 上使用 MinGW&#xff0c;基于 GCC-8.1.0 的 posix-sjlj 线程版本5&#xff0c;研究一下怎么编译…