Java/Python读取Android logcat文件行数异常求助
日志文件读取行数翻倍问题的原因与解决办法
我需要从Android logcat导出的TXT日志文件中提取两类数值并写入独立文件,确认提取逻辑正常,但Java和Python读取时都出现行数异常:文件实际有10367行,Python统计得20735行(刚好是两倍)。
可能原因
- 换行符识别差异:Android日志默认用
\n作为换行符,但如果日志中混入了单独的\r(回车符),Python/Java的默认读取逻辑会将\r也视为换行分隔符,导致单一行被拆分为两行,行数直接翻倍。 - 编码不匹配:若日志文件采用UTF-16等双字节编码,但代码以UTF-8读取,会导致字节解析错误,误将部分字节识别为换行符。
- 日志内容内嵌换行:部分日志行本身包含换行符(如多行堆栈信息),文本编辑器将其合并显示为一行,但代码按实际换行符分割,导致统计行数增加。
解决办法
1. 强制指定换行符
Python中打开文件时,通过newline='\n'参数强制仅将\n视为换行符,避免误识别\r:
with open("C:\\Users\\yusuf\\OneDrive\\Masaüstü\\SpeedTests\\Logs\\log100.txt", 'r', newline='\n') as inFile:
Java端若需严格识别\n,可自定义读取逻辑,逐字符读取并过滤\r:
BufferedReader br = new BufferedReader(new FileReader(file)) { @Override public String readLine() throws IOException { StringBuilder sb = new StringBuilder(); int c; while ((c = read()) != -1) { if (c == '\n') break; if (c != '\r') sb.append((char) c); } return sb.length() > 0 ? sb.toString() : null; } };
2. 预处理统一换行符
读取每行后手动移除\r字符,避免其干扰:
Python:
for line in inFile: line = line.rstrip('\r\n') + '\n' # 统一为\n结尾 # 后续提取逻辑
Java:
String line; while ((line = br.readLine()) != null) { line = line.replace("\r", ""); # 后续提取逻辑 }
3. 验证并匹配文件编码
用Python的chardet库检测文件编码,再指定编码打开:
import chardet with open("log100.txt", 'rb') as f: encoding_info = chardet.detect(f.read()) with open("log100.txt", 'r', encoding=encoding_info['encoding'], newline='\n') as inFile: # 读取逻辑
4. 修复代码中的小错误
- Python代码中
i变量未初始化,需添加i=0;写入total文件时错误写入ssString,应改为stString:def main(): i = 0 # 初始化计数器 # ... 其他代码 with open("C:\\Users\\yusuf\\OneDrive\\Masaüstü\\SpeedTests\\Results\\total100.txt",'w') as outFile: outFile.write(stString) # 修正为stString - Java代码中缺少
writeToFile实现,需补充:private static void writeToFile(String fileName, String content) throws IOException { try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))) { bw.write(content); } }
原始代码
Python代码
def main(): serverSpeedsList=list() totalSpeedsList=list() ssString=str() stString=str() with open("C:\\Users\\yusuf\\OneDrive\\Masaüstü\\SpeedTests\\Logs\\log100.txt",'r') as inFile: for line in inFile: i+=1 ss=speedOfServer(line) st=speedOfTotal(line) if ss!="": ssString+=ss+"\n" serverSpeedsList.append(ss) if st!="": stString+=st+"\n" totalSpeedsList.append(st) with open("C:\\Users\\yusuf\\OneDrive\\Masaüstü\\SpeedTests\\Results\\server100.txt",'w') as outFile: outFile.write(ssString) with open("C:\\Users\\yusuf\\OneDrive\\Masaüstü\\SpeedTests\\Results\\total100.txt",'w') as outFile: outFile.write(ssString) def speedOfServer(text): startStr="time\":\"" endStr=" ms" result=str() startIx=text.find(startStr) endIx=text.find(endStr) if startIx>=0 and endIx>=0: result=text[startIx+len(startStr) : endIx] return result def speedOfTotal(text): startStr="showProfile.php (" endStr="ms" result=str() startIx=text.find(startStr) endIx=text.find(endStr) if startIx>=0 and endIx>=0: result=text[startIx+len(startStr) : endIx] return result main()
Java代码
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Main { private static String serverSpeedFileName="C:\\Users\\yusuf\\OneDrive\\Masaüstü\\JavaSpeedAnalyser\\Results\\Server\\serverSpeed100.txt"; private static String responseSpeedFileName="C:\\Users\\yusuf\\OneDrive\\Masaüstü\\JavaSpeedAnalyser\\Results\\Total\\responseSpeed100.txt"; private static String logFilePath="C:\\Users\\yusuf\\OneDrive\\Masaüstü\\JavaSpeedAnalyser\\Logs\\log100.txt"; public static void main(String[] args){ StringBuilder serverSpeeds=new StringBuilder(); StringBuilder responseSpeeds=new StringBuilder(); try{ File file = new File(logFilePath); BufferedReader br = new BufferedReader(new FileReader(file)); String line; while ((line = br.readLine()) != null){ String serverSpeed=speedOfServer(line); if(!serverSpeed.isEmpty()){ System.out.println(serverSpeed); serverSpeeds.append(serverSpeed+"\n"); } String responseSpeed=speedOfResponses(line); if(!responseSpeed.isEmpty()){ responseSpeeds.append(responseSpeed+"\n"); } } br.close(); }catch(IOException e){ e.printStackTrace(); } writeToFile(serverSpeedFileName, serverSpeeds.toString()); writeToFile(responseSpeedFileName, responseSpeeds.toString()); } private static String speedOfServer(String text){ String start="time\":\""; String end=" ms"; String result=""; int startIndex=text.indexOf(start); int endIndex=text.indexOf(end); if(startIndex>=0 && endIndex>=0 ){ result=text.substring(startIndex+start.length(),endIndex); } return result; } private static String speedOfResponses(String text){ String start="%5bF%5dshowProfile.php ("; String end="ms)"; String result=""; int startIndex=text.indexOf(start); int endIndex=text.indexOf(end); if(startIndex>=0 && endIndex>=0){ result=text.substring(startIndex+start.length(),endIndex); } return result; } }
内容的提问来源于stack exchange,提问作者yusufff
相关产品推荐
相关产品推荐

