编码时间:
2024.03.29
编码内容:
- CsInputInt 从控制台输入整数
- FileUtilRe按行读取文件内容(文本文件)
- FileUtileWr按行写入文件内容
- DBUtil数据库基本操作
使用方法:
- CsInputInt.java
new CsInputInt().InputInt()
- FlReadByLine.java
FlReadByLine flReadLine = new FlReadByLine();
List<String> list = flReadLine.readFileLines(inPath);//inPath为要读的目标文件地址 读取的数据存入List
- FlWriteByLine.java
FlWriteByLine flWriteLine = new FlWriteByLine();
flWriteLine.writeFileLines(outpath, list, true);//outpath:要写的目标文件路径。 list:一个列表(方法实现将列表的数据按行写入文件)。true:布尔值,true为追加写入文件,false为覆盖写入文件
详细实现:
- CsInputInt .java
package com.CommonClass;
import java.util.Scanner;
public class CsInputInt {
Scanner scanner = new Scanner(System.in); // 创建一个Scanner对象用于从System.in读取输入
/**
* 从用户处接收一个整数输入。
*
* @return 输入的整数值
*/
public int InputInt() {
System.out.println("请输入一个整数");
String str = scanner.nextLine(); // 获取用户输入的字符串
while (!isInt(str)) { // 检查输入是否为整数,直到输入合法
System.out.println("您输入的不是整数,请重新输入");
str = scanner.nextLine(); // 要求用户重新输入
}
System.out.println("您输入的整数是:" + str);
return Integer.parseInt(str); // 将字符串转换为整数并返回
}
/**
* 检查提供的字符串是否可以解析为整数。
*
* @param str 需要检查的字符串
* @return 如果字符串可以解析为整数,则返回true;否则返回false。
*/
public boolean isInt(String str) {
try {
Integer.parseInt(str); // 尝试将字符串解析为整数
return true; // 如果没有抛出异常,表示可以解析为整数,返回true
} catch (NumberFormatException e) {
return false; // 如果抛出异常,表示无法解析为整数,返回false
}
}
}
- FileUtilRe.java
package com.CommonClass;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class FileUtilRe {
/**
* 读取文件内容
*
* @param filePath 文件路径
* @return 文件的完整内容,如果文件不存在或读取过程中发生错误,则返回null
*/
// 定义一个方法,参数为文件路径(String类型)
public List<String> readFileLines(String filePath) {
// 创建一个ArrayList对象,用于存储文件的每一行内容
List<String> lines = new ArrayList<>();
// 使用try-with-resources语句,确保BufferedReader关闭,即使在读取过程中出现异常
try (BufferedReader reader = new BufferedReader(
// 创建一个InputStreamReader对象,以指定的UTF-8字符集读取文件
new InputStreamReader(new FileInputStream(filePath), StandardCharsets.UTF_8))) {
// 声明一个临时变量line,用于存储当前读取到的行
String line;
// 循环读取文件,直到没有更多行可读
while ((line = reader.readLine()) != null) {
// 将读取到的每一行添加到lines列表中
lines.add(line);
}
// 如果正常执行到这里,说明文件读取完毕,返回包含所有行内容的列表
return lines;
} catch (FileNotFoundException e) {
// 如果文件未找到,输出错误信息,并打印堆栈跟踪信息
System.err.println("文件 " + filePath + " 未找到!");
e.printStackTrace();
// 返回null表示读取失败
return null;
} catch (IOException e) {
// 如果在读取文件过程中发生任何IO异常,输出错误信息,并打印堆栈跟踪信息
System.err.println("读取文件过程中发生错误!");
e.printStackTrace();
// 返回null表示读取失败
return null;
}
}
}
/*
* FileInputStream 是 Java 内置的一个类,它是 InputStream 的具体实现,用于读取文件中的原始字节流。
* 当你需要从硬盘上的文件读取二进制数据时,会使用 FileInputStream,它按照字节流的方式工作,逐字节地读取文件内容。
*
* InputStreamReader 是一个字符流,它继承自 Reader 类。
* 本身并不直接读取文件,而是包装在它内部的字节流之上,提供从字节流到字符流的转换服务。 它使用指定的字符集将字节流解码为字符流,以便处理文本内容。
*/
/*
* BufferedReader 是 Java 中的一个标准类,它是 java.io.Reader * 的子类,设计用于高效地读取字符流中的文本数据。
* 当需要从诸如文件、网络连接等来源读取大量文本内容时,使用 BufferedReader * 能够显著提高读取效率,
* 因为它采用了缓冲技术,能够在内存中暂存一部分数据,而不是每次读取一个字符都要进行磁盘或网络访问。
*
* 主要特点与用途:
*
* 缓冲机制:BufferedReader 维护了一个内部缓冲区,当调用 read() 或 readLine()
* 等方法时,它首先从缓冲区中获取数据,只有当缓冲区的数据耗尽时,才会从底层流(如 FileReader)加载更多的数据。
*
* 高效读取:BufferedReader 提供了高效的按行读取方法 readLine(),这使得遍历文件的每一行变得简单快捷。 相比于每次调用 read()
* 方法循环判断换行符,这种方式极大地提高了程序性能。
*
* 支持标记和重置:BufferedReader 支持 mark() 和 reset()
* 方法,允许在输入流中标记一个位置,然后在稍后的时间点恢复到该位置,这对需要回滚读取状态的场景非常有用。
*/
- FileUtileWr.java
package com.CommonClass;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
public class FileUtileWr {
public boolean writeFileLines(String path, List<String> list, boolean writeway) throws IOException {
File outfile = new File(path);
if (!outfile.exists()) { // 检查文件是否存在,如果不存在则创建
outfile.createNewFile();
}
/*
* 创建 BufferedWriter:为了高效地写入文本数据,使用 new BufferedWriter(new
* OutputStreamWriter(new FileOutputStream(outfile, false))) 创建一个 BufferedWriter
* 对象。其中:
*
* new FileOutputStream(outfil e, false) 表示以覆盖模式打开文件,false
* 参数意味着如果文件已存在,则将其内容清空,而不是追加内容。 OutputStreamWriter 负责将字符转换为字节流,以便与
* FileOutputStream 协同工作。 BufferedWriter 提供缓冲功能,提高写入效率。
*/
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(outfile, writeway)))) {
for (String line : list) {
writer.write(line);
writer.newLine(); // 使用 BufferedWriter 的新行写入方法
}
// writer.flush(); // 在全部写完后再flush该行删去是因为因为它使用了 try-with-resources 语句自动关闭
// BufferedWriter,关闭前会自动刷新。
}
return true;
}
// 这是写的第一版,也能实现,有需要优化的地方为:
// 使用 try-with-resources 结构确保 FileOutputStream 在完成写入后会被自动关闭,即使发生异常也能正确关闭流。
// 尽可能减少频繁的 flush() 调用,可以在整个写入过程结束后调用一次。
// 使用 BufferedWriter 对 FileOutputStream 进行包装,利用其缓冲机制提升写入效率。
// public boolean writeFileLines(String path, List<String> list) throws
// IOException {
// File outfile = new File(path);
// System.out.println(outfile.canWrite());
// FileOutputStream fileOutputStream = new FileOutputStream(outfile);
// for (String line : list) {
// fileOutputStream.write(line.getBytes());
//
// fileOutputStream.write("\n".getBytes());
//
// fileOutputStream.flush();
// }
// fileOutputStream.close();
// return true;
}
- DBUtil.java
package com.CommonClass;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DBUtil {
/**
* 日志记录器,用于记录操作日志。
*/
private static final Logger LOGGER = Logger.getLogger(DBUtil.class.getName());
/**
* 数据库驱动名。
*/
private String driver = "com.mysql.cj.jdbc.Driver";
/**
* 数据库主机地址。
*/
private String host = "10.3.12.87";
/**
* 数据库端口号。
*/
private int port = 3306;
/**
* 数据库用户名。
*/
private String user = "user003";
/**
* 数据库密码。
*/
private String password = "Aa123456";
/**
* 数据库名称。
*/
private String dbName = "study";
/**
* 数据库连接,使用volatile修饰以保证内存可见性,并使用double-checked locking模式确保线程安全。
*/
private volatile Connection conn = null;
/**
* 锁对象,用于double-checked locking模式。
*/
private static final Object lock = new Object();
/**
* 加载数据库驱动。 尝试加载指定的数据库驱动,如果加载失败,则记录日志。
*/
public void loadDrive() {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
LOGGER.log(Level.SEVERE, "加载驱动失败", e);
}
}
/**
* 获取数据库连接。 使用double-checked locking模式确保线程安全地初始化单例连接。
*
* @return Connection 数据库连接对象。
*/
public Connection dbConn() {
new DBUtil().loadDrive(); // 每次调用获取连接时都先加载驱动,确保驱动已加载。
String url = "jdbc:mysql://" + host + ":" + port + "/" + dbName;
if (conn == null) {
synchronized (lock) {
if (conn == null) { // double-checked locking模式,确保仅初始化一次连接。
try {
conn = DriverManager.getConnection(url, user, password);
System.out.println("连接数据库成功!");
} catch (SQLException e) {
// 日志记录连接失败的具体异常信息
LOGGER.log(Level.SEVERE, "连接数据库失败", e);
}
}
}
}
return conn;
}
public void closeConn(Connection conn) {
if (conn == null) {
// 如果传入的连接为null,则直接返回,不做处理
return;
}
// 使用try-with-resources语句自动关闭Connection资源
try (Connection autoCloseableConn = conn) {
// 此处可以添加其他逻辑,但无需手动关闭连接
} catch (SQLException e) {
// 使用日志记录异常信息,而不是直接打印堆栈跟踪
LOGGER.log(Level.SEVERE, "Failed to close database connection.", e);
// 可根据需要在这里添加更多的异常处理逻辑,例如重新抛出为运行时异常等
}
}
public int executeUpdate(Connection conn,String sql, Object... params) {
//Object... params 是Java中可变参数列表的语法,也称为“不定长参数”。在函数定义中使用这种语法,允许调用者传入任意数量的同类型参数。
try (
PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
return pstmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("执行SQL更新语句失败: " + sql, e);
}
}
}