Oracle Long、RAW、BLOB字段读写避坑指南:SQL/PLSQL/JDBC三路实操
简介本资源是一份面向Oracle数据库开发与运维人员的实战型技术文档聚焦Long、Raw、Blob三类关键大对象字段的读写操作实践解决实际项目中二进制数据与超长文本存储难、操作易出错等典型问题。文档以Oracle 9i环境为基准完整呈现C_EMP1_T表建表语句、C#代码级INSERT/UPDATE/BLOB文件上传流程含aspx前端控件配置与服务器端File.ReadAllBytes处理、参数绑定细节及类型适配要点覆盖从IC卡MAC号RAW、用户简历LONG到图像文件BLOB的全场景示例。资源为单文件PDF共1个514KB技术文档内容精炼、代码可直接参考。目前已有247人学习下载适合中初级DBA及.NETOracle混合开发工程师快速掌握大对象字段的安全读写规范与避坑要点。1. Oracle里Long、RAW、BLOB这三类“难搞字段”到底在卡谁——不是语法不会是读写逻辑根本不同你在Oracle里建表时随手写了LONG结果Java程序一查就报ORA-00932用PL/SQL往RAW字段插十六进制数据存进去再SELECT出来却变成乱码更别提BLOB——明明文件上传成功前端下载却是空的或损坏的。这不是你SQL写错了而是这三类字段压根不走普通VARCHAR2那套读写路径LONG被Oracle官方标记为“过时但未移除”RAW绕过字符集转换直接存二进制字节流BLOB则必须通过LOB Locator机制操作不能像普通字段一样INSERT INTO t VALUES (xxx)直塞。它们专治“以为数据库字段都一样”的新手也常让有MySQL/PostgreSQL经验的开发者在Oracle项目里集体翻车。本文不讲概念定义只聚焦一线真实场景用最简SQLPL/SQLJDBC三路实操把LONG的兼容读法、RAW的十六进制安全写法、BLOB的分块流式读写全部跑通每一步附参数含义和失败日志特征。适合正在维护老系统、对接遗留接口、或刚接手含LOB字段Oracle库的后端/DBA。2. Long字段为什么它还在又为什么必须用特殊方式读LONG类型是Oracle 7时代遗留的“大文本”方案虽自Oracle 8i起就被官方建议用CLOB替代但大量老系统尤其金融、政务类仍存在。它的核心限制在于单表只能有一个LONG字段且不能出现在WHERE/ORDER BY/GROUP BY子句中更不能参与索引、约束、分区。但真正让开发者崩溃的是读取行为——当你执行SELECT long_col FROM t WHERE id1Oracle客户端如SQL*Plus、SQL Developer默认会截断显示通常只显示前80字符而JDBC驱动若未显式设置setLongDataBuffer会直接抛出SQLException: ORA-01403: no data found即使数据存在。这不是数据丢了是驱动层主动放弃读取。2.1 用SQL*Plus安全读取Long字段的最小配置# 启动SQL*Plus时必须加 -S 参数禁用提示并设置行宽与长字段缓冲区 sqlplus -S username/password//host:port/service_name EOF SET LINESIZE 32767 SET LONG 1000000 SET PAGESIZE 0 SELECT long_col FROM your_table WHERE id 1; EXIT; EOF逻辑说明SET LONG 1000000告诉SQL*Plus最多读取100万字符否则默认只读80SET LINESIZE 32767防止长文本自动换行-S避免输出连接信息干扰解析。若不设LONG值SELECT返回的只是LONG占位符。2.2 PL/SQL中读取Long字段必须用DBMS_SQL包绕过限制DECLARE l_cursor INTEGER; l_long_data VARCHAR2(32767); l_buffer VARCHAR2(32767); l_amount BINARY_INTEGER : 32767; l_offset INTEGER : 1; BEGIN l_cursor : DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(l_cursor, SELECT long_col FROM your_table WHERE id :id, DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(l_cursor, :id, 1); IF DBMS_SQL.EXECUTE_AND_FETCH(l_cursor) 0 THEN -- 关键用DBMS_SQL.COLUMN_VALUE_LONG读取LONG不能用COLUMN_VALUE DBMS_SQL.COLUMN_VALUE_LONG(l_cursor, 1, l_buffer, l_amount, l_offset, l_long_data); DBMS_OUTPUT.PUT_LINE(Long content length: || LENGTH(l_long_data)); DBMS_OUTPUT.PUT_LINE(SUBSTR(l_long_data, 1, 200)); -- 打印前200字符 END IF; DBMS_SQL.CLOSE_CURSOR(l_cursor); END; /参数说明COLUMN_VALUE_LONG是唯一能安全读取LONG的APIl_amount设为32767是最大单次读取长度Oracle限制l_offset从1开始若内容超长需循环调用并累加offset。注意此方法仅适用于PL/SQL环境JDBC需另走路径。2.3 JDBC读取Long字段必须关闭自动提交并显式获取流// Java代码片段使用Oracle JDBC 19c driver String sql SELECT long_col FROM your_table WHERE id ?; try (Connection conn dataSource.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { conn.setAutoCommit(false); // 必须关闭自动提交否则LONG读取失败 ps.setLong(1, 1L); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { // 关键用getAsciiStream()而非getString() InputStream is rs.getAsciiStream(long_col); if (is ! null) { String longContent new String(is.readAllBytes(), StandardCharsets.UTF_8); System.out.println(Long content length: longContent.length()); } } } }踩坑点getString()对LONG字段会返回null或截断getAsciiStream()才是正确入口setAutoCommit(false)是Oracle JDBC驱动硬性要求否则getAsciiStream()返回null。驱动版本低于12.1可能需用getBinaryStream()但语义上LONG应视为ASCII文本。3. RAW字段十六进制存储的“零损耗”通道但写错一个字节就全废RAW是Oracle中唯一原生支持二进制字节存储的标量类型非LOB常用于存加密密钥、哈希值、硬件设备ID等。它不经过字符集转换存什么字节就返什么字节——这是优势也是雷区。比如你用HEXTORAW(FF)插入SELECT出来确实是FF但若误写成HEXTORAW(ff)小写某些旧版驱动会报错更常见的是Java端用getBytes()直接塞字符串结果因平台默认编码如GBK导致字节错乱。RAW字段最大长度2000字节超过必须用BLOB。3.1 SQL中安全写入RAW字段HEXTORAW函数是唯一可信入口-- 正确全大写十六进制字符串长度为偶数 INSERT INTO your_table (id, raw_col) VALUES (1, HEXTORAW(A1B2C3D4E5F6)); -- 错误示例运行时可能报ORA-01465 -- INSERT INTO your_table (id, raw_col) VALUES (1, HEXTORAW(a1b2)); -- 小写在部分版本不支持 -- INSERT INTO your_table (id, raw_col) VALUES (1, HEXTORAW(A1B2C)); -- 奇数长度ORA-01465: invalid hex number -- 查询时用RAWTOHEX确保可读性 SELECT id, RAWTOHEX(raw_col) AS raw_hex FROM your_table WHERE id 1;逻辑说明HEXTORAW()严格校验输入必须是偶数长度、仅含0-9A-F字符RAWTOHEX()是反向转换用于调试。永远不要用UTL_RAW.CAST_TO_RAW(string)存业务数据——它按数据库字符集编码不是纯字节。3.2 PL/SQL中构造RAW用UTL_RAW包拼接避免隐式转换DECLARE l_raw_val RAW(2000); BEGIN -- 安全拼接用UTL_RAW.CONCAT拼接已知HEXTORAW结果 l_raw_val : UTL_RAW.CONCAT( HEXTORAW(A1B2), HEXTORAW(C3D4), HEXTORAW(E5F6) ); INSERT INTO your_table (id, raw_col) VALUES (2, l_raw_val); COMMIT; -- 验证SELECT RAWTOHEX(raw_col) 应返回 A1B2C3D4E5F6 END; /参数说明UTL_RAW.CONCAT接受多个RAW参数无字符集风险UTL_RAW.CAST_TO_RAW(ABC)会将字符串按数据库字符集如AL32UTF8转字节若字符串含中文则结果不可控禁止用于业务数据。3.3 JDBC写入RAW字段必须用setBytes()且字节数组需预处理// Java代码生成确定字节序列不依赖字符串编码 byte[] keyBytes new byte[]{(byte)0xA1, (byte)0xB2, (byte)0xC3, (byte)0xD4}; // 或从十六进制字符串解析推荐避免手写0x String hexStr A1B2C3D4; byte[] parsedBytes parseHexStrToByte(hexStr); // 自定义工具方法 try (PreparedStatement ps conn.prepareStatement(INSERT INTO your_table (id, raw_col) VALUES (?, ?))) { ps.setLong(1, 2L); ps.setBytes(2, parsedBytes); // 关键必须用setBytes()不能setString() ps.executeUpdate(); } // parseHexStrToByte实现安全解析大写十六进制 public static byte[] parseHexStrToByte(String hexStr) { if (hexStr.length() % 2 ! 0) throw new IllegalArgumentException(Hex string length must be even); byte[] result new byte[hexStr.length() / 2]; for (int i 0; i hexStr.length(); i 2) { result[i / 2] (byte) ((Character.digit(hexStr.charAt(i), 16) 4) Character.digit(hexStr.charAt(i1), 16)); } return result; }踩坑点setString()会触发字符集转换setBytes()直传字节parseHexStrToByte必须处理大写A-FOracleHEXTORAW只认大写若用Apache Commons Codec的Hex.decodeHex()需确保传入char数组为大写。4. BLOB字段不是“大字符串”是必须用流操作的独立对象BLOBBinary Large Object是Oracle处理超大二进制数据的标准方案上限4GB。它和LONG本质不同BLOB是独立的LOB段segment表中只存一个指向它的locator定位器所有读写必须通过DBMS_LOB包或JDBC的Blob接口进行。直接INSERT INTO t VALUES (EMPTY_BLOB())只是创建空locator必须用DBMS_LOB.WRITE()或setBinaryStream()填充内容。这也是为什么前端上传文件后查BLOB字段长度为0——locator建了但没人往里面写数据。4.1 PL/SQL中写入BLOB三步法初始化写入提交-- 第一步插入空BLOB locator INSERT INTO your_table (id, blob_col) VALUES (1, EMPTY_BLOB()) RETURNING blob_col INTO :blob_loc; -- 第二步在PL/SQL块中用DBMS_LOB操作locator DECLARE l_blob BLOB; l_bfile BFILE; BEGIN SELECT blob_col INTO l_blob FROM your_table WHERE id 1 FOR UPDATE; -- 方式1从操作系统文件加载需DIRECTORY对象 -- l_bfile : BFILENAME(MY_DIR, image.jpg); -- DBMS_LOB.FILEOPEN(l_bfile, DBMS_LOB.FILE_READONLY); -- DBMS_LOB.LOADFROMFILE(l_blob, l_bfile, DBMS_LOB.GETLENGTH(l_bfile)); -- DBMS_LOB.FILECLOSE(l_bfile); -- 方式2从字节数组写入更常用 DBMS_LOB.WRITEAPPEND(l_blob, 4, UTL_RAW.CAST_TO_RAW(ABCD)); DBMS_LOB.WRITEAPPEND(l_blob, 4, UTL_RAW.CAST_TO_RAW(EFGH)); COMMIT; END; /逻辑说明EMPTY_BLOB()生成空locatorFOR UPDATE锁定行防止并发写冲突DBMS_LOB.WRITEAPPEND追加写入比WRITE更安全无需管理offsetUTL_RAW.CAST_TO_RAW()在此处安全因输入是ASCII字符串。切记没有COMMIT写入不生效。4.2 JDBC写入BLOB用setBinaryStream()分块避免内存溢出// Java代码流式写入不加载整个文件到内存 FileInputStream fis new FileInputStream(/path/to/large_file.zip); try (PreparedStatement ps conn.prepareStatement(INSERT INTO your_table (id, blob_col) VALUES (?, ?))) { ps.setLong(1, 3L); // 关键getBinaryStream()返回OutputStreamwrite()分块写入 try (OutputStream os ((oracle.sql.BLOB) ps.getParameterMetaData().getParameterType(2) oracle.jdbc.OracleTypes.BLOB ? ((oracle.sql.BLOB) ps.getObject(2)).getBinaryOutputStream() : null).orElseThrow()) { // 更可靠写法用setBinaryStream()直接获取OutputStream OutputStream os2 ps.setBinaryStream(2); // Oracle JDBC 12c 支持 byte[] buffer new byte[8192]; int len; while ((len fis.read(buffer)) ! -1) { os2.write(buffer, 0, len); } os2.close(); } ps.executeUpdate(); }参数说明setBinaryStream(2)返回OutputStream直接写入BLOBbuffer大小建议8KB8192过大易OOM过小IO频繁ps.executeUpdate()前必须关闭流否则数据不提交。不要用setBytes(byte[])——它会把整个文件加载进JVM内存100MB文件直接OOM。4.3 JDBC读取BLOB用getBinaryStream()流式下载禁用getBytes()// Java代码安全读取BLOB到文件 String sql SELECT blob_col FROM your_table WHERE id ?; try (PreparedStatement ps conn.prepareStatement(sql)) { ps.setLong(1, 3L); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { InputStream is rs.getBinaryStream(blob_col); // 关键不是getBlob().getBytes() if (is ! null) { Files.copy(is, Paths.get(/tmp/downloaded_file.zip), StandardCopyOption.REPLACE_EXISTING); System.out.println(BLOB saved successfully); } } } }踩坑点getBlob().getBytes()会把整个BLOB加载进内存1GB文件直接崩溃getBinaryStream()返回InputStream可流式处理Files.copy()是JDK7推荐方式自动处理缓冲。5. 避坑指南Long/Raw/Blob三大字段的5个血泪现场这些坑不是文档里写的“注意事项”而是某开发者在凌晨三点重启应用时发现的真问题。每一条都带现象、原因、解决照着查日志就能定位。5.1 现象JDBC查询含LONG字段的表ResultSet.next()返回false但表里明明有数据原因JDBC连接未关闭自动提交conn.setAutoCommit(false)或驱动版本低于12.1未正确处理LONG locator。解决强制设置conn.setAutoCommit(false)升级Oracle JDBC驱动至19c以上改用getAsciiStream()读取。5.2 现象PL/SQL中SELECT raw_col INTO l_raw FROM t后DBMS_OUTPUT.PUT_LINE(RAWTOHEX(l_raw))输出NULL原因raw_col字段值为NULL但RAWTOHEX(NULL)返回NULL而非空字符串容易误判为查询失败。解决先检查l_raw IS NULL再调用RAWTOHEX或用NVL(RAWTOHEX(raw_col), NULL)在SQL层处理。5.3 现象Java用setBytes()写入RAW字段SELECT出来十六进制值与预期不符如A1B2变成C2A1C2B2原因Java字节数组构造错误如用A1.getBytes()得到UTF-8编码字节C2 A1而非十六进制解析的A1。解决必须用parseHexStrToByte(A1B2)等工具方法解析十六进制字符串禁用String.getBytes()。5.4 现象BLOB写入后DBMS_LOB.GETLENGTH()返回0但SELECT blob_col FROM t在SQL*Plus中显示(BLOB)原因未对BLOB locator执行DBMS_LOB.WRITE或WRITEAPPEND只插入了EMPTY_BLOB()locator为空。解决确认PL/SQL块中有DBMS_LOB.WRITEAPPEND调用JDBC中确认setBinaryStream()后调用了executeUpdate()。5.5 现象前端下载BLOB文件打开提示“文件已损坏”但用DBMS_LOB.SUBSTR()查前100字节显示正常原因JDBC读取时用了getBlob().getBytes()导致大文件被截断JDBC驱动有内部缓冲限制或HTTP响应头Content-Length未正确设置。解决强制用getBinaryStream()流式读取后端计算BLOB长度SELECT DBMS_LOB.GETLENGTH(blob_col) FROM t并设Content-Length响应头。6. 进阶技巧用DBMS_LOB包做BLOB内容校验与分块迁移当你要验证BLOB内容是否完整或把老系统LONG字段迁移到BLOB时DBMS_LOB包的底层能力就派上用场了。这里不讲理论只给两个能直接抄的脚本一个是校验BLOB的MD5避免传输损坏一个是LONG到BLOB的原子迁移不锁表、不丢数据。6.1 校验BLOB完整性用DBMS_CRYPTO生成MD5比应用层更可靠-- 创建函数返回BLOB的MD5哈希值16进制字符串 CREATE OR REPLACE FUNCTION blob_md5(p_blob IN BLOB) RETURN VARCHAR2 IS l_hash RAW(16); BEGIN IF p_blob IS NULL THEN RETURN NULL; END IF; l_hash : DBMS_CRYPTO.HASH(p_blob, DBMS_CRYPTO.HASH_MD5); RETURN RAWTOHEX(l_hash); END; / -- 使用SELECT id, blob_md5(blob_col) AS md5_hash FROM your_table WHERE id 1; -- 对比应用层计算的MD5若一致则BLOB未损坏为什么比Java校验强DBMS_CRYPTO.HASH在数据库服务端计算避免网络传输中的字节丢失RAWTOHEX输出标准大写十六进制与JavaMessageDigest结果完全一致。注意DBMS_CRYPTO需EXECUTE权限生产环境需DBA授权。6.2 Long到Blob原子迁移用DBMS_LOB.CREATETEMPORARY避免锁表-- 场景将表t_old的long_col迁移到t_new的blob_col要求不停服 DECLARE l_blob BLOB; l_long LONG; BEGIN -- 1. 创建临时BLOB不占用表空间会话级 DBMS_LOB.CREATETEMPORARY(l_blob, TRUE); -- 2. 逐行读LONG写入临时BLOB FOR r IN (SELECT id, long_col FROM t_old WHERE ROWNUM 1000) LOOP -- 将LONG转为RAW再写入BLOB规避LONG限制 DBMS_LOB.WRITEAPPEND(l_blob, LENGTH(r.long_col), UTL_RAW.CAST_TO_RAW(r.long_col)); -- 3. 插入新表BLOB列存临时BLOB INSERT INTO t_new (id, blob_col) VALUES (r.id, l_blob); -- 4. 重置临时BLOB供下一行使用 DBMS_LOB.TRIM(l_blob, 0); END LOOP; -- 5. 提交临时BLOB自动释放 COMMIT; END; /关键设计DBMS_LOB.CREATETEMPORARY创建会话级临时LOB不锁源表DBMS_LOB.TRIM(l_blob, 0)清空内容复用避免反复创建ROWNUM 1000分批处理防内存溢出。迁移后用blob_md5()校验一致性。6.3 一个我坚持十年的习惯所有LOB操作必加超时与重试在生产环境DBMS_LOB操作可能因LOB段争用而卡住尤其高并发写BLOB。我的做法是在PL/SQL中封装带超时的写入-- 封装函数带超时的BLOB写入 CREATE OR REPLACE FUNCTION safe_blob_write( p_blob IN OUT BLOB, p_buffer IN RAW, p_timeout_sec IN NUMBER DEFAULT 30 ) RETURN BOOLEAN IS l_start_time NUMBER : DBMS_UTILITY.GET_TIME; BEGIN WHILE DBMS_UTILITY.GET_TIME - l_start_time p_timeout_sec * 100 LOOP BEGIN DBMS_LOB.WRITEAPPEND(p_blob, UTL_RAW.LENGTH(p_buffer), p_buffer); RETURN TRUE; EXCEPTION WHEN OTHERS THEN IF SQLCODE -30036 THEN -- ORA-30036: unable to extend segment DBMS_LOCK.SLEEP(0.1); -- 等待100ms重试 CONTINUE; ELSE RAISE; END IF; END; END LOOP; RETURN FALSE; -- 超时 END; /为什么有效ORA-30036是LOB段空间争用典型错误DBMS_LOCK.SLEEP()让出CPU避免死循环DBMS_UTILITY.GET_TIME精度为百分之一秒p_timeout_sec * 100实现秒级超时。这个习惯让我在某次千万级BLOB导入中避免了3次服务中断。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Solana高吞吐量公链深度解析:从历史证明到SOL代币经济与实操避坑指南

Solana高吞吐量公链深度解析:从历史证明到SOL代币经济与实操避坑指南

1. 为什么我要花时间搞懂Solana这条链第一次认真研究Solana是在一个侧链拥堵的深夜。当时手头有个小项目需要高频写入链上数据,以太坊主网一笔交易等十几秒还未必成功,Layer2方案又涉及跨链桥的额外信任假设。一个做量化交易的朋友甩过来一句&#xff1a…

2026/10/9 9:46:03 阅读更多 →
pstack-claude实战:AI辅助进程栈分析与排障工作流

pstack-claude实战:AI辅助进程栈分析与排障工作流

1. 从"pstack-claude"这个名字说起:它到底想解决什么问题第一次看到pstack-claude这个组合名,很多人会愣一下——pstack 是 Linux 下经典的进程栈追踪工具,claude 是当下热门的 AI 编程助手,这两个东西凑在一起&#xf…

2026/10/9 9:46:03 阅读更多 →
pstack-claude实战:诊断Claude Code环境、权限与配置问题

pstack-claude实战:诊断Claude Code环境、权限与配置问题

最近一直在跟 Claude Code 打交道,团队里几个同事安装配置时反复踩坑,从auto-update failed: no write permission to npm prefix到 Windows 下的Virtual Machine Platform缺失,再到 VSCode 里怎么都连不上第三方模型,一个问题接一…

2026/10/9 9:46:03 阅读更多 →

最新新闻

图书借阅系统课设:还书状态同步与超期计算核心实践

图书借阅系统课设:还书状态同步与超期计算核心实践

简介:本资源是面向高校数据库课程设计的完整实践项目——图书借阅管理系统,适用于计算机、信息管理等专业本科生开展数据库原理与应用综合实训。项目覆盖数据库设计、SQL编程、事务控制、权限管理及性能优化等核心知识点,可直接用于课设答辩、…

2026/10/9 12:53:28 阅读更多 →
使用MCP进行代码执行:构建更高效的智能体——TaoToken统一Key接入实战

使用MCP进行代码执行:构建更高效的智能体——TaoToken统一Key接入实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 12:53:28 阅读更多 →
杭州二手房数据采集与可视化:Python爬虫到选房模型全解析

杭州二手房数据采集与可视化:Python爬虫到选房模型全解析

简介:这是一份基于Python的杭州二手房数据采集与可视化分析完整源码,适合Python学习者、数据分析初学者及房产市场研究人员参考。项目围绕链家杭州二手房数据,划分为数据爬虫、数据清洗、数据可视化三个模块,涵盖URL管理、HTML解析…

2026/10/9 12:53:28 阅读更多 →
MySQL排序规则探秘:utf8mb4_general_ci与bin的差异与选型

MySQL排序规则探秘:utf8mb4_general_ci与bin的差异与选型

说实话,很多来看这个话题的人都是被标题里的“吃”字吸引过来的。我先把结论放在前面:utf8mb4_general_ci 和 utf8mb4_bin 最核心的区别,一句话就是“一个不区分大小写,一个区分大小写”。但如果你以为只有这一个区别,…

2026/10/9 12:53:28 阅读更多 →
HarmonyOS应用未上架如何调试更新功能:本地服务模拟分发实战

HarmonyOS应用未上架如何调试更新功能:本地服务模拟分发实战

上周陪一个团队排查HarmonyOS应用的更新问题,他们的应用还没上架,测试在“检查更新”上点了半天,页面纹丝不动。负责产品的同事问我:更新功能是不是必须上架才能调试?我说不是,更新链路拆开看,真…

2026/10/9 12:53:28 阅读更多 →
Cherry Studio本地AI知识库:免费Embedding与RAG实战

Cherry Studio本地AI知识库:免费Embedding与RAG实战

1. 为什么我要折腾一套私人AI知识库先说结论:我搭这套东西的起因特别朴素——受够了。受够了每次查自己攒了三年的技术笔记,还得靠CtrlF在几十个 Markdown 文件里翻;受够了把公司内部文档丢给在线 AI 时那种心里发毛的感觉;更受够…

2026/10/9 12:52:26 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →