// 2026-04-25 | test_json_debug_clean.dart | 详细调试 _cleanJsonContent import 'dart:io'; import 'dart:convert'; void main() { final path = r'e:\program files (x86)\wegame\apps\2821981550\filerecv\小妈厨房 - 数据导出(1).json'; print('📁 读取文件...\n'); final bytes = File(path).readAsBytesSync(); var content = utf8.decode(bytes, allowMalformed: true); print('原始内容:'); print(' 长度: ${content.length}'); print(' 最后一个字符: "${content[content.length - 1]}" (${content.codeUnitAt(content.length - 1)})'); print(''); // 模拟 _cleanJsonContentPage 的每一步 print('🧹 执行 _cleanJsonContentPage:\n'); // 步骤1: 移除BOM content = content.replaceFirst(RegExp('^\\uFEFF'), ''); print('步骤1 - 移除BOM后长度: ${content.length}'); print(''); // 步骤2: 检查最后一个 } final lastBrace = content.lastIndexOf('}'); print('步骤2 - 最后一个 } 在位置: $lastBrace (总长度: ${content.length})'); if (lastBrace >= 0 && lastBrace < content.length - 1) { final trailing = content.substring(lastBrace + 1).trim(); print(' } 之后的内容: "$trailing" (${trailing.length}字符)'); print(' 内容的hex编码:'); for (var i = 0; i < (trailing).length; i++) { print(' [$i] U+${trailing.codeUnitAt(i).toRadixString(16).toUpperCase().padLeft(4, '0')} "${trailing[i]}"'); } if (trailing.isNotEmpty && !trailing.startsWith(',') && !trailing.startsWith('}') && !trailing.startsWith(']')) { print(' ⚠️ 将截取到位置 ${lastBrace + 1}'); content = content.substring(0, lastBrace + 1); print(' 截取后长度: ${content.length}'); } else { print(' ✅ 不需要截取'); } } else if (lastBrace == content.length - 1) { print(' ✅ 最后一个字符就是 }'); } else { print(' ❌ 没有找到 }'); } print(''); // 步骤3: 检查最后一个 ] final lastBracket = content.lastIndexOf(']'); print('步骤3 - 最后一个 ] 在位置: $lastBracket (当前长度: ${content.length})'); if (lastBracket >= 0 && lastBracket < content.length - 1) { final trailing = content.substring(lastBracket + 1).trim(); print(' ] 之后的内容: "$trailing" (${trailing.length}字符)'); if (trailing.isNotEmpty) { print(' ⚠️ 将截取到位置 ${lastBracket + 1}'); content = content.substring(0, lastBracket + 1); print(' 截取后长度: ${content.length}'); } else { print(' ✅ 不需要截取'); } } else if (lastBracket == content.length - 1) { print(' ✅ 最后一个字符就是 ]'); } else { print(' ❌ 没有找到 ]'); } print(''); // 步骤4: 移除控制字符 final beforeControl = content.length; content = content.replaceAll(RegExp(r'[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]'), ''); if (content.length != beforeControl) { print('步骤4 - 移除了 ${beforeControl - content.length} 个控制字符'); } else { print('步骤4 - 无控制字符需要移除'); } print(''); // 步骤5: trim final beforeTrim = content.length; content = content.trim(); if (content.length != beforeTrim) { print('步骤5 - trim移除了 ${beforeTrim - content.length} 个空白字符'); } else { print('步骤5 - 无空白字符需要trim'); } print(''); // 最终结果 print('✅ 最终结果:'); print(' 长度: ${content.length}'); print(' 最后10个字符: ...${content.length > 10 ? content.substring(content.length - 10) : content}'); print(''); // 尝试解析 print('🔍 尝试 jsonDecode...'); try { final decoded = jsonDecode(content); print('✅ 解析成功!'); if (decoded is Map) { print(' Keys: ${decoded.keys.join(', ')}'); // 检查浏览记录 if (decoded.containsKey('browse_history')) { final history = decoded['browse_history']; if (history is List) { print(' 浏览记录数: ${history.length}'); } } } } catch (e) { print('❌ 解析失败: $e'); print(''); // 显示错误位置的上下文 final lines = content.split('\n'); print(' 总行数: ${lines.length}'); final lineMatch = RegExp(r'line (\d+)').firstMatch(e.toString()); final charMatch = RegExp(r'character (\d+)').firstMatch(e.toString()); if (lineMatch != null) { final errorLine = int.tryParse(lineMatch.group(1) ?? '0') ?? 0; final errorChar = int.tryParse(charMatch?.group(1) ?? '0') ?? 0; print(' 错误位置: 第${errorLine}行, 第${errorChar}个字符'); if (errorLine > 0 && errorLine <= lines.length) { print(' 该行内容: "${lines[errorLine - 1]}"'); // 括号平衡检查 var braceCount = 0; var bracketCount = 0; for (var i = 0; i < errorLine; i++) { final line = lines[i]; for (var j = 0; j < line.length; j++) { final char = line[j]; if (char == '{') braceCount++; if (char == '}') braceCount--; if (char == '[') bracketCount++; if (char == ']') bracketCount--; } } print(' 到该行前的括号平衡: {=$braceCount [=$bracketCount'); } } } }