Python 基礎 - 文件操作_v2
嗯,那如何要把游標的位置給打印來?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())---------------執行結果---------------0Process finished with exit code 0
那在試試把文件讀完後,再打印一次游標位置
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())
print(f.readline())
print(f.tell())---------------執行結果---------------
0
Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言129 # 129個字符,記得換行符號要也算進去哦Process finished with exit code 0
唔…不相信?是129個字符,好吧,那就用另一個方式read()
來呈現好了,預設read()
不指定的話,是讀取所有的,因此我們這次使用read(6)
來試試,看看是不是真的為6
個字符
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())
print(f.read(6))
print(f.tell())---------------執行結果---------------0
Python
6Process finished with exit code 0
嗯嗯,真的是6
個字符,那通常我們還是會用readline()
,因為這樣不用去數這一行有幾個字符,直接幫你讀取整行,那假設我們現在讀取了三行後,要怎麼讓游標回到一開始?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
f.seek(0)
print(f.readline())---------------執行結果---------------0
Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言它包含了一組功能完備的標準庫,能夠輕鬆完成很多常見的任務。它的語法簡單,與其它大多數程式設計語言使用大括弧不一樣,它使用縮進來定義語句塊與Scheme、Ruby、Perl、Tcl等動態語言一樣,Python具備垃圾回收功能,能夠自動管理記憶體使用454
Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言Process finished with exit code 0
唔…觀察一下,游標真的回到一開始了,原來使用seek(0)
就可以了,通常tell()
會跟seek()
一起使用,tell()
會打印出目前游標的位置,seek()
可以指定游標的位置停在哪裡
那如果要檢查文件是用什麼字符編碼的,要怎麼查呢?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.readline())
print(f.encoding)---------------執行結果---------------Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言UTF-8Process finished with exit code 0
唔,看到打印出UTF-8
了,這樣就可以確定了
觀察一下,下面代碼的fileno()
跟name()
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open("test", "wb")
print ("Name of the file: ", f.name)fid = f.fileno()
print ("File Descriptor: ", fid)---------------執行結果---------------Name of the file: foo.txt
File Descriptor: 3
fileno()
這個是作業系統專門的接口,專門去調度系统的 I/O 操作,這個接口是提供給所有程式語言使用,並不是Python才會有的
name()
這個是打印出文件名字,很簡單吧
isatty()
就是判斷是不是一個終端設備,為真返回True
,這個較少用
seekable()
不是所有的文件都可以移動游標,這個主要是拿來判斷普通文件裡的游標能不能移動,為真返回True
readable()
判斷文件是不是可讀的權限,為真返回True
writable()
判斷文件是不是可寫的權限,為真返回True
flush()
即時地把記憶體中的緩衝區裡的資料,立刻寫回至文件中,同時清空緩衝區,一般情況下,文件關閉後會自動刷新緩衝區,但有時你需要在關閉前刷新它,這時就可以使用 flush()
方法
下面我們來做一下實驗,先在terminal開二個分頁,一個用python3執行,進行互動模式,另一個用tail -f foo.txt
即時地去監看這個文件的變化,當我在分頁一執行flush()
時,看看分頁二裡的文件是不是即時地被寫入
唔…看起來flush()
的使用情境就是上圖的用法
接下來做一個比較有趣的應用,來實做一個進度條
#!/usr/bin/env python3
# -*- coding:utf-8 -*-import sys, timefor i in range(20):sys.stdout.write("#")sys.stdout.flush()time.sleep(0.5)
這個代碼,各位可以試試看,挺有趣的應用…
closed
判斷文件是不是關閉,為真返回True
再來講一下 truncate()
,這個是截斷字符串用的
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'a', encoding='utf-8')
f.truncate()---------------執行結果---------------Hello Python
Hello Python1
Hello Python2
Hello Python3
Hello Python4
打開文件的模式改成用a
,發現並不會去截斷字符串,那如果改成truncate(4)
,看看會有什麼不同?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'a', encoding='utf-8')
f.truncate(4)---------------執行結果---------------Hell
觀察發現,怎麼字符串從第四個之後被截斷了,這是因為truncate(4)
的關係,那我們在加入先前學到的seek()
,能不能從特定指定的位置之後開始截斷字符串,那要怎麼做呢?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'a', encoding='utf-8')
f.seek(10)
f.truncate(7)---------------執行結果---------------Hello P
有發現了嗎?怎麼還是一樣是從頭開始截7個字符串
,完全沒有依照原本的想像,從指定的第10個字符串開始往後截斷,所以由此可知,truncate()
截斷的標準,完全不受seek()
影響的
先前示範的代碼都只能讀
或只能寫
,接下來我們讓讀寫
同時在一起好了,也順便觀察一下,有什麼不一樣的地方
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'r+', encoding='utf-8')
print(f.readline())
print(f.readline())
f.write("----------我是分隔線----------")
print(f.readline())---------------執行結果---------------Hello Python
Hello Python1
Hello Python2
Hello Python3
Hello Python4----------我是分隔線----------
咦,奇怪了,怎麼不是在第二行寫入----------我是分隔線----------
,怎麼跑到最後一行了?等於其實因為是r+
這個關係,是用讀取跟寫入
的方式打開文件,不相信?好吧,那我們就來打印一下游標位置,確認一下是怎麼運作
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'r+', encoding='utf-8')
print(f.readline())
print(f.readline())
print(f.tell())
f.write("----------我是分隔線----------")
print(f.readline())---------------執行結果---------------Hello PythonHello Python127
Hello Python2Process finished with exit code 0觀察文件內容:
Hello Python
Hello Python1
Hello Python2
Hello Python3
Hello Python4----------我是分隔線--------------------我是分隔線----------
觀察一下,上面的代碼,的確真的是以讀寫
的方法打開文件了,那剛剛使用r+
,那換使用w+
,觀察一下,跟r+
有什麼不同?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'w+', encoding='utf-8')
print(f.readline())
print(f.readline())
print(f.tell())
f.write("----------我是分隔線----------")
print(f.readline())---------------執行結果---------------0Process finished with exit code 0觀察文件內容:
----------我是分隔線----------
唔!!!怎麼只剩一行----------我是分隔線----------
?這是因為f = open('foo.txt', 'w+', encoding='utf-8')
這一句的關係,先打開一個文件叫foo.txt
,接著因為w
會有truncate
的作用,所以不管原本文件裡面有什麼,都會被清空,然後在用寫入
至文件裡面,所以上面的代碼執行完畢後,才會只剩下一行,又不相信?好吧,那就再來實驗一下,確認一下到底是怎麼運作的…
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'w+', encoding='utf-8')
print("目前游標起始位置:", f.tell())
f.write("----------我是第一行----------\n")
f.write("----------我是第二行----------\n")
f.write("----------我是第三行----------\n")
f.write("----------我是第四行----------\n")
f.write("----------我是第五行----------\n")
print("目前游標位置:", f.tell())
f.seek(10)
print("游標返回的位置:", f.tell())
print(f.readline())
f.write("My name is Tony Stark, I'm ironman")
print("最後游標的位置:", f.tell())
f.close()---------------執行結果---------------目前游標起始位置: 0
目前游標位置: 180
游標返回的位置: 10
我是第一行----------最後游標的位置: 214Process finished with exit code 0觀察文件內容:
----------我是第一行----------
----------我是第二行----------
----------我是第三行----------
----------我是第四行----------
----------我是第五行----------
My name is Tony Stark, I'm ironman
咦,正常應該要從我是第一行----------
這邊開始寫入的,但就是真的沒辦法寫,因為w+
是做寫入更新
,所以即使游標返回特定位置,一樣不受影響,只會寫在文件裡的最後一行
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'rb', encoding='utf-8') # 讀取二進制文件
print(f.readline())
print(f.readline())
print(f.readline())
f.close()---------------執行結果---------------Traceback (most recent call last):File "/Python/project/path/file_operation.py", line 4, in <module>f = open('foo.txt', 'rb', encoding='utf-8') # 讀取二進制文件
ValueError: binary mode doesn't take an encoding argumentProcess finished with exit code 1
若是讀取二進制
文件,就不需要傳encoding
編碼的參數給它,否則就會報錯,試試把encoding
拿掉看看會有什麼結果?
接下來實做一下怎麼對二進制文件
做操作
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'rb') # 讀取二進制文件
print(f.readline())
print(f.readline())
print(f.readline())
f.close()---------------執行結果---------------b'----------\xe6\x88\x91\xe6\x98\xaf\xe7\xac\xac\xe4\xb8\x80\xe8\xa1\x8c----------\n'
b'----------\xe6\x88\x91\xe6\x98\xaf\xe7\xac\xac\xe4\xba\x8c\xe8\xa1\x8c----------\n'
b'----------\xe6\x88\x91\xe6\x98\xaf\xe7\xac\xac\xe4\xb8\x89\xe8\xa1\x8c----------\n'Process finished with exit code 0
有看到前面多了一個b
代表這個是一個bytes-like
這個就是指二進制的文件
- 網路傳送,只能用二進制進行傳送
- 讀取二進制的文件
那既然有rb
,也就有wb
,那就來看一下怎麼用?
f = open('foo.txt', 'wb') # 寫入二進制文件
f.write("Hello Binary\n")
f.close()---------------執行結果---------------Traceback (most recent call last):File "/Python/project/path/file_operation.py", line 4, in <module>f = open('fooo.txt', 'rb') # 讀取二進制文件
TypeError: a bytes-like object is required, not 'str'Process finished with exit code 1
出現TypeError: a bytes-like object is required, not 'str'
這是說明不能是一個字符串,所以我們要把字符串
轉成bytes類型(可以回頭參考一下)
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'wb') # 寫入二進制文件
f.write("Hello Binary\n".encode())
f.close()---------------執行結果---------------
觀察文件內容:Hello Binary
咦!奇怪,為什麼看到的還是一個字符串?其實存的時候不是以0101儲存的
,而是文件以二進制編碼儲存
知識點:
U
表示在讀取時,會將\r
、\n
、\r\n
自動轉換成\n
(與 r 或 r+ 模式使用)
- rU
- r+U
b
表示處理二進制文件 (如:FTP上傳ISO檔的文件,Linux可以怱略,但windows處理二進制文件時,需要標注)
修改文件有二種方法,一種是把文件裡的所有資料,都暫時存到記憶體裡,找到要修改的文字,然後再回存至文件裡,就像vim
一樣,另一種是rename
的方式,也就是建立另一個新的文件,然後修改完原本的文件後,寫入至新文件,那我們就來實做第二種方式
準備好二個文件,一個是foo
裡面要有內容,另一個新文件是空的 - foo.bak
foo文件內容如下
柯文哲扮演1位到西門町刺青的Rocker,但因實在太怕痛而刺不下去
而柯文哲還以為是真的要在身上刺青
還說「啊?是真的要刺下去嗎?我還沒跟我老婆報備呢。」
foo.bak文件內容如下
要把『是真的要刺下去嗎』
修改成 『不是真的要刺下去吧』
,並寫入至foo.bak
那要怎麼做咧?
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open("foo", "r", encoding="utf-8")
f_new = open("foo.bak", "w", encoding="utf-8")for line in f:if "是真的要刺下去嗎" in line:line = line.replace("是真的要刺下去嗎", "不是真的要刺下去吧")f_new.write(line)else:f_new.write(line)
f.close()
f_new.close()
f = open("foo", "r", encoding="utf-8")
只用讀取模式找到要修改的字符串f_new = open("foo.bak", "w", encoding="utf-8")
用寫入模式,是把上面找到修改後的字符串寫入至新文件裡if "是真的要刺下去嗎" in line:
先找出要修改的字符串- 用
replace()
來做修改字符串
可以優化成下面代碼
#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open("foo.txt", "r", encoding="utf-8")
f_new = open("foo.bak", "w", encoding="utf-8")for line in f:if "是真的要刺下去嗎" in line:line = line.replace("是真的要刺下去嗎", "不是真的要刺下去吧")f_new.write(line)
f.close()
f_new.close()
觀察一下foo.bak文件內容
柯文哲扮演1位到西門町刺青的Rocker,但因實在太怕痛而刺不下去
而柯文哲還以為是真的要在身上刺青
還說「啊?不是真的要刺下去吧?我還沒跟我老婆報備呢。」
嗯!確實已經修改了,但上面的代碼,還是寫的不夠好,因為是寫死的,那如果我想讓用戶自已輸入想要替換的文字,那要怎麼做呢?
請在Terminal中執行 $python3 sed.py 是真的要刺下去嗎 不是真的要刺下去吧
#!/usr/bin/env python3
# -*- coding:utf-8 -*-import sysfind_sys = sys.argv[1]
replace_sys = sys.argv[2]f = open("foo.txt", "r", encoding="utf-8")
f_new = open("foo.bak", "w", encoding="utf-8")for line in f:if find_sys in line:line = line.replace(find_sys, replace_sys)f_new.write(line)
f.close()
f_new.close()
在執行這代碼前,先砍掉foo.bak
,確認不存在後,再執行上面的代碼,然後觀察一下是不是真的有替換了
那之前在操作文件時,有沒有發現常常有的代碼會寫f.close()
,有的沒有寫,其實這是在操作文件時很容易被忽略,所以現在要介紹一個好物,with語句
,它會主動幫我們關閉文件,並釋放文件資源,所以可以寫成下面的代碼,就不需要在額外寫f.close()
了,這樣就輕鬆一點了
with opne("file.txt", "r", encoding="utf-8") as f:...
所以上面的代碼還可以再優化
#!/usr/bin/env python3
# -*- coding:utf-8 -*-import sysfind_sys = sys.argv[1]
replace_sys = sys.argv[2]with open("foo.txt", "r", encoding="utf-8") as f, \open("foo.bak", "w", encoding="utf-8") as f_new:for line in f:if find_sys in line:line = line.replace(find_sys, replace_sys)f_new.write(line)
同樣在terminal執行上面的代碼
參考資料:
- fileno
转载于:https://www.cnblogs.com/zarr12steven/p/6209668.html
Python 基礎 - 文件操作_v2相关推荐
- 從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎
"Talk is cheap. Show me the code." ― Linus Torvalds 老子第41章 上德若谷 大白若辱 大方無隅 大器晚成 大音希聲 大象無形 道 ...
- python 对 yaml 文件操作
python 对 yaml 文件操作 #!/usr/bin/env python # -*- encoding: utf-8 -*- """ @Introduce : p ...
- Python实现tab文件操作
Python实现tab文件操作 # -*- coding:gbk -*- import os class TABFILE: def __init__(self, filename, dest_ ...
- python怎么读取文件-python怎么读写文件操作
本节内容:I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input/ ...
- python处理excel教程实例-python 读写excel文件操作示例【附源码下载】
本文实例讲述了python 读写excel文件操作.分享给大家供大家参考,具体如下: 对excel文件的操作,python有第三方的工具包支持,xlutils,在这个工具包中包含了xlrd,xlwt等 ...
- Python中的文件操作和异常
Python中的文件操作和异常 文章目录 Python中的文件操作和异常 一.文件 01. 文件的概念 1.1 文件的概念和作用 1.2 文件的存储方式 文本文件和二进制文件 02. 文件的基本操作 ...
- Python os模块文件操作(二)
Python os模块文件操作(二) os模块对文件夹和文件的操作很多.可以先看: https://blog.csdn.net/weixin_43790276/article/details/9867 ...
- Python os模块文件操作(一)
Python os模块文件操作(一) 一.文件描述符 在使用代码对文件进行操作时,为了指定操作的文件,避免不了要使用文件描述符,所以我们先介绍什么是文件描述符. 操作系统为了高效管理已经被打开的文件, ...
- python怎么读写文件-python怎么读写文件操作
本节内容:I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input/ ...
最新文章
- 如何防止SSH会话断开连接
- FFMPEG结构体分析之AVFormatContext
- PHP vs Node.js vs Nginx-Lua(转)
- 在c语言中load,一道题理清Objective-C中的load和initialize
- [JLOI2014]松鼠的新家
- 将视图转为image_使用视图绑定替代 findViewById
- PyTorch 入坑六 数据处理模块Dataloader、Dataset、Transforms
- 程序员招聘面试那些奇葩 | 文末附高薪内推
- Windows上更换鼠标指针图标
- QQ,MSN,旺旺在线客服代码
- Nebula Graph 系列(1) —— 初识 Nebula
- 来自资深会员管理人的深度思考
- c语言double型小数点后几位_double类型的数据在输出的时候,C语言编译器对小数部分可以精确到小数点后面的第几位?...
- Infrared and Visible Image Fusion using a Deep Learning Framework解析
- 04UE4 C++ 入门【力和扭矩】
- Fastadmin一键生成菜单栏目
- C++题目分享之冰雹猜想
- Ambari+HDP+HDP-UTILS下载地址大全
- 芯科技之AD7656介绍
- delegate、传值、跳转页面