Python读取txt文件与其他文件的区别探究!
1.根本区别:文本文件 vs 二进制文件
# 查看文件类型importos files=['test.txt','test.docx','test.xlsx','test.pdf','test.html','test.json']"""十一剑的CS_DN博客出品"""forfileinfiles:ifos.path.exists(file):withopen(file,'rb')asf:# 二进制模式查看header=f.read(100)# 读取前100字节print(f"{file:15}头部:{header[:20]}...")2.各种文件的本质和读取原理
a. TXT 文本文件
# 最简单:纯字符流 + 换行符# 文件内容: "Hello\nWorld\n"# 存储格式: 48 65 6C 6C 6F 0A 57 6F 72 6C 64 0A (ASCII/UTF-8编码)withopen('test.txt','r')asf:# 文本模式lines=f.readlines()# 按换行符分割"""十一剑的CS_DN博客出品"""# 底层:读取字节流 → 解码为字符串 → 按\n分割b. HTML 文件
# 本质:也是文本文件,但有标签结构# <!DOCTYPE html># <html><body><p>Hello</p></body></html>withopen('page.html','r',encoding='utf-8')asf:# 1. 可以像文本一样逐行读取forlineinf:print(line)"""十一剑的CS_DN博客出品"""# 2. 但通常用解析器读取结构化数据frombs4importBeautifulSoup soup=BeautifulSoup(f,'html.parser')# 解析器识别的是:标签、属性、文本内容c. JSON 文件
# 本质:文本文件,但有严格的语法结构# {"name": "John", "age": 30, "hobbies": ["reading", "swimming"]}importjsonwithopen('data.json','r')asf:# 1. 文本模式读取content=f.read()# 得到字符串"""十一剑的CS_DN博客出品"""# 2. JSON解析器识别的是:# - 大括号 {} 表示对象# - 中括号 [] 表示数组# - 冒号 : 分隔键值# - 逗号 , 分隔元素data=json.loads(content)# 解析为Python数据结构d. Excel 文件(.xlsx)
# 本质:ZIP压缩包 + XML文件# 实际是多个文件:# - [Content_Types].xml# - xl/workbook.xml# - xl/worksheets/sheet1.xml# - xl/sharedStrings.xml# - xl/styles.xmlimportzipfile# 解压查看内部结构withzipfile.ZipFile('test.xlsx','r')asz:print(z.namelist())# 读取工作表内容withz.open('xl/worksheets/sheet1.xml')asf:xml_content=f.read().decode('utf-8')# 识别的是XML标签:<row r="1"><c r="A1"><v>100</v></c></row>"""十一剑的CS_DN博客出品"""# 使用库读取importopenpyxl wb=openpyxl.load_workbook('test.xlsx')ws=wb.active# openpyxl解析的是:单元格坐标、公式、样式等e. Word 文件(.docx)
# 本质:也是ZIP压缩包 + XML# 包含:# - word/document.xml # 主要内容# - word/styles.xml # 样式# - word/_rels/ # 关系importzipfileimportxml.etree.ElementTreeasETwithzipfile.ZipFile('test.docx','r')asz:# 读取主文档withz.open('word/document.xml')asf:xml_content=f.read()root=ET.fromstring(xml_content)# 识别XML命名空间和标签:# <w:p>段落</w:p># <w:r>文本运行</w:r># <w:t>文本内容</w:t>"""十一剑的CS_DN博客出品"""# 使用库读取fromdocximportDocument doc=Document('test.docx')# python-docx解析的是:段落、样式、表格、图片等f. PDF 文件
# 本质:二进制格式,有固定结构# PDF结构:# %PDF-1.7 # 头部# 1 0 obj # 对象1# << /Type /Catalog# /Pages 2 0 R >># endobj# 2 0 obj # 对象2(页面树)# ...# xref # 交叉引用表# trailer # 尾部# %%EOF # 结束标记# 原始查看withopen('test.pdf','rb')asf:header=f.read(1000)# 识别的是:对象引用、流、字典、操作符等"""十一剑的CS_DN博客出品"""# 使用库读取importPyPDF2withopen('test.pdf','rb')asf:reader=PyPDF2.PdfReader(f)# PyPDF2解析的是:页面树、内容流、字体、图像等3.各种文件解析的"识别"内容对比表
| 文件类型 | 本质格式 | 解析器识别的内容 | 读取方式 |
|---|---|---|---|
| TXT | 纯文本 | 换行符、编码字符 | 按字节/字符流 |
| HTML | 文本+标签 | 标签、属性、文本节点 | DOM树解析 |
| JSON | 结构化文本 | 大括号、中括号、冒号、逗号 | 语法解析器 |
| Excel | ZIP+XML | 工作表、单元格、公式、样式 | 解压+XML解析 |
| Word | ZIP+XML | 段落、样式、表格、图片 | 解压+XML解析 |
| 二进制结构化 | 对象、流、字典、操作符 | 二进制解析 | |
| “”“十一剑的CS_DN博客出品”“” |
4.底层原理深度对比
# 模拟各种解析器的工作方式(概念代码)classFileParser:"""不同文件解析器的概念实现""""""十一剑的CS_DN博客出品"""defparse_txt(self,content):"""TXT:按换行符分割"""returncontent.split('\n')defparse_html(self,content):"""HTML:解析标签树"""# 简化版,实际更复杂tags=[]i=0whilei<len(content):ifcontent[i]=='<':# 找到标签j=content.find('>',i)tag=content[i:j+1]tags.append(tag)i=j+1else:i+=1returntagsdefparse_json(self,content):"""JSON:解析结构化数据"""# 简化版importjsonreturnjson.loads(content)defparse_excel_xml(self,xml_content):"""Excel XML解析"""# 查找单元格cells=[]start=0whileTrue:# 查找 <c> 标签c_start=xml_content.find('<c ',start)ifc_start==-1:break# 查找值v_start=xml_content.find('<v>',c_start)v_end=xml_content.find('</v>',v_start)ifv_start!=-1andv_end!=-1:value=xml_content[v_start+3:v_end]cells.append(value)start=c_start+1returncellsdefparse_pdf_objects(self,binary_data):"""PDF对象解析"""# PDF对象示例:1 0 obj ... endobjobjects=[]data_str=binary_data.decode('latin-1',errors='ignore')obj_start=0whileTrue:# 查找 "obj"obj_pos=data_str.find(' obj',obj_start)ifobj_pos==-1:break# 查找 "endobj"end_pos=data_str.find('endobj',obj_pos)ifend_pos==-1:breakobj_content=data_str[obj_pos:end_pos]objects.append(obj_content)obj_start=end_pos+6returnobjects5.实际文件结构示例
# 创建各种文件并查看原始内容importjsonimportpandasaspdfromdocximportDocument# 1. 创建JSON文件data={"users":[{"name":"Alice","age":25},{"name":"Bob","age":30}]}withopen('test.json','w')asf:json.dump(data,f,indent=2)# 查看原始内容withopen('test.json','rb')asf:print("JSON原始内容(前200字节):")print(f.read(200))# 看到的是:{\n "users": [\n {\n "name": "Alice",\n "age": 25\n },\n ...# 2. 创建简单的Excel文件df=pd.DataFrame({'A':[1,2],'B':[3,4]})df.to_excel('test.xlsx',index=False)"""十一剑的CS_DN博客出品"""# 查看ZIP结构importzipfilewithzipfile.ZipFile('test.xlsx')asz:print("\nExcel文件内部结构:")fornameinz.namelist():if'sheet'inname:print(f"{name}")withz.open(name)asf:content=f.read(500).decode('utf-8')print(f" 内容示例:{content[:200]}...")# 3. 创建PDF并查看结构fromreportlab.pdfgenimportcanvas c=canvas.Canvas("test.pdf")c.drawString(100,750,"Hello PDF")c.save()withopen('test.pdf','rb')asf:print("\nPDF文件头部:")print(f.read(500).decode('latin-1',errors='ignore'))6.专业库如何工作
# 以PDF为例,看专业解析器的工作流程classSimplePDFParser:"""简化的PDF解析器概念"""def__init__(self,filename):self.filename=filenamedefparse(self):withopen(self.filename,'rb')asf:# 1. 验证PDF头部header=f.read(8)ifnotheader.startswith(b'%PDF-'):raiseValueError("不是有效的PDF文件")# 2. 定位交叉引用表f.seek(-50,2)# 从末尾开始tail=f.read()# 3. 查找xrefxref_pos=tail.find(b'xref')# 4. 读取对象# ... 复杂解析过程return{'pages':[],'fonts':[],'images':[]}# 实际使用专业库importPyPDF2"""十一剑的CS_DN博客出品"""defanalyze_pdf_structure(filename):"""分析PDF结构"""withopen(filename,'rb')asf:reader=PyPDF2.PdfReader(f)print(f"PDF版本:{reader.pdf_header}")print(f"页数:{len(reader.pages)}")print(f"元数据:{reader.metadata}")# 查看第一页的内容流ifreader.pages:page=reader.pages[0]if'/Contents'inpage:contents=page['/Contents']ifhasattr(contents,'get_data'):data=contents.get_data()print(f"内容流大小:{len(data)}字节")敲黑板!!@!!(十一剑的CS_DN博客)
TXT/HTML/JSON:都是文本文件,按字符读取
- TXT识别换行符
- HTML识别标签和属性
- JSON识别语法结构
Excel/Word (.docx):ZIP压缩的XML文件
- 需要解压后解析XML
- 识别的是结构化文档元素
PDF:复杂的二进制格式
- 有严格的内部结构(对象、流、字典)
- 需要专门的二进制解析器
图像/音频/视频:又是完全不同的二进制格式
- 识别的是像素、音频采样、视频帧等
核心区别:
- 文本文件:处理字符和编码
- 结构化文档:处理标记语言和对象模型
- 二进制格式:处理字节流和特定数据结构
每种文件格式都有其独特的文件签名(Magic Number)和内部结构,解析器需要针对性地设计和实现。