在磁盤上讀寫文件的功能都是由操做系統提供的,現代操做系統不容許普通的程序直接操做磁盤,因此,讀寫文件就是請求操做系統打開一個文件對象(一般稱爲文件描述符),而後,經過操做系統提供的接口從這個文件對象中讀取數據(讀文件),或者把數據寫入這個文件對象(寫文件)。
文件是計算機中由OS管理的具備名字的存儲區域,在Linux中,文件是被看作字節序列.python
open(文件目錄(能夠是絕對路徑和相對路徑)[文件打開模式][文件輸出緩存])
後面兩項是可選參數。默認返回是一個文件對象的內存,其默認的讀寫模式是隻讀模式,mysql
能夠經過賦值進行輸出結果read(輸出的字節數)默認是所有
經過參數指定讀取的範圍:
redis
A seek([文件偏移量][文件指針位置])
文件指針的返回
爲0表示文件的起始,爲1 表示當前位置,爲2表示末尾位置。
經過指定文件的指針能夠重複讀取文件的第一行內容,sql
偏移量的大小表現爲文件的字節數,當爲正時,表示向右讀取,當爲負時,表示向左讀取,當爲0時,表示不偏移shell
B tell()顯示指針目前所處位置
C close()表示關閉當前文件
D closed 檢查當前文件是否關閉,若爲True ,則表示已關閉,若爲False,則表示未關閉
E name 查看文件名稱
F mode 查看當前文件的打開模式
G flush 將當前文件的內容刷新到磁盤上,其目的是爲了防止斷電而保存。
H next() 用於讀取文件內容,每次讀取一行,其指針位置不發生變化
數據庫
A readline()每次讀取一行文件內容
B readlines() 每次讀取文件的全部內容
C read () 指定讀取文件的字節數,默認是所有讀取windows
A write()其能夠寫入字符串,
B writelins()用於傳入多個參數
緩存
編碼:用一個字節表明什麼,兩個字節表明什麼,
編碼問題:
1 Windows的默認編碼規則是cp936國標,cp936是GBK 的一種,GBK不是國際標準,GB2312是國際標準。
2 Linux的默認編碼規則是utf-8,Unicode傳輸編碼,其一個漢字是3個字節,偶爾多是4個字節,其總共佔6個字節
Gbk 是 a0 開始的,在utf-8中不能識別
GBK 是順序的中文編碼,GBK是兩個字節。utf-8大可能是3個字節,多是4個字節
換行符問題:網絡
可以使用newline進行指定換行符,文本模式中,換行的轉換能夠爲None,"",'\r','\n','\r\n'
讀取時,None 標識'\r','\n','\r\n'都被轉換爲'\n', ""(空字符串)表示、
不會自動轉換通用換行符,其餘合法字符表示換行符就是指定字符,就會按照自定字符分行,從新定義分割符。socket寫入時,None 表示"\n"都會被替換爲系統缺省分割符os.linsep,'\n'或"" 表示"\n"不替換,其餘合法字符表示
換行符"\n"都會被替換爲指定分割符。
文件描述符:
默認的三種,0 標準輸入, 1 標準輸出, 2 錯誤輸出
文件描述符可表示打開文件的數量,當打開文件數量達到系統打開文件數量上限時,則會報錯
seek(offset[,whence])
offset默認是針對於起始位置開始,表示從頭測試
文本模式下:
whence=0 缺省值,表示從頭開始,offset只能接受正整數
whence=1 表示從當前位置開始,offset 只接受0
whence=2 表示從EOF 開始,offset 只接受0
二進制模式:
whence=0 缺省值,表示從頭開始offset只能是正整數
whence=1 表示從當前位置開始,offset可正可負
whence=2 表示從EOF開始,offset可正可負
二進模式支持任意起點的偏移,從頭,從尾,從中間位置開始向後seek能夠超界,可是向前seek的時候,不能超界,不然會報異常。
size 表示讀取多少個字符或字節,負數或None表示讀取到EOF
流對象,字符序列,字節序列,網絡流至沒有邊界 ,都指的是序列,
網絡流:和時間有關,也是一個序列
文本流,字符流,
二進制流,字節流: 將文件就按照字節理解,與字符編碼無關,二進制模式操做時,字節操做使用bytes類型
f=open('test2','wb') f.write("愛國".encode()) #此處使用字節輸入,其默認編碼是utf-8, print (f) f.close() f=open('test2') # 此處讀取,默認編碼是utf-8 print (f) print (f.read(1)) print (f.read(1)) f.close()
結果以下:
在Linux 中,執行
查看打開文件狀況
因爲打開文件未關閉,致使打開文件數過多,每次打開文件都會產生文件表述符,則致使問題,Linux默認的打開文件數量是1024,其因爲未關閉而致使有如上報錯。
解決方式1
經過異常處理進行關閉。
with open('test2') as f: f.write("zhongguo") print (f.closed)
結果以下
做用:用於將python與文件系統更加緊密鏈接的一種模塊
os.Chdir() 改變目錄/經過文件描述改變工做目錄
os.chroot() 設定當前進程的根目錄
os.listdir() 列出指定目錄下的全部文件名
os.Mkdir()建立指定目錄,默認爲一級
os.makedirs('x/y/z')
os.getcwd()獲取當前目錄
os.Rmdir()刪除目錄
os.Removedirs() 刪除多級目錄
os.removedirs('/mnt/aaa/bbb/ccc') 必須制定全部的目錄才能夠刪除
os.mkfifo() 建立先進先出管道(命名
os.mknod() :建立設備文件
os.Remove() 刪除文件
os.Unlink( ) 刪除連接
os.Rename() 文件重命名
os.rename('passwd','aaa')
os.Stat() 返回文件狀態信息
os.Symlink() 建立文件連接,符號連接
In [33]: os.symlink('text2.txt','text2.syslink')
text2.syslink
os.utime() 更新文件的事件戳 updatetime
os.tmpfile() 建立並打開一個新的臨時文件,打開模式是(w+b)
os.access() 檢驗權限模式
In [42]: os.access('/tmp/text2.txt',0) UID 管理員的訪問權限
os.Out[42]: True
In [43]: os.access('/tmp/text2.txt',100) 普通用戶的訪問權限
Out[43]: False
os.Chmod() 修改權限
In [44]: os.chmod('text2.txt',0640) os.chmod('aaa',0777)爲四位
os.Chwon 修改屬主 ,屬組
In [47]: os.chown('text2.txt',1000,1000)
[root@www tmp]# id admin
uid=1000(admin) gid=1000(admin) 組=1000(admin)
[root@www tmp]# ll text2.txt
-rw-r-----. 1 admin admin 2525 11月 19 20:35 text2.txt
os.Umask() 設置默認權限模式
os.Open():打開一個文件,底層操做系統的open
os.Read() 較低io的讀取操做
os.Write() 較低IO的寫操做
os.Mkdev() 根據指定的主設備號,次設備號建立文件
In [48]: help(os.makedev)
Help on built-in function makedev in module posix:makedev(...)
makedev(major, minor) -> device number
Composes a raw device number from the major and minor device numbers.
(END)
os.Major() 從指定的設備獲取主設備號
os.Minor() 從指定的設備獲取次設備號
1 os.system 用於python 與shell之間的交互命令,若是存在,則返回0,不然返回其餘
os.popen(命令).read()
os.uname() 獲取當前模塊的詳細信息
In [55]: import os.path
A.os.path.Basename():路徑基名
In [58]: file1=os.path.basename('/etc/sysconfig/netw')
/etc/sysconfig/network /etc/sysconfig/network-scripts/B.os.path.irname() 路徑目錄名
C.os.path.join() 將路徑基名和目錄名整合成一個名字
In [60]: os.path.join(dir1,file1)
Out[60]: '/etc/sysconfig/network-scripts/'
In [63]: for filename in os.listdir('/tmp'):
....: print os.path.join('/tmp',filename)C. os.path.splist()分割文件名和文件,返回dir和basename()元組
In [64]: os.path.split('/etc/sysconfig/')
Out[64]: ('/etc/sysconfig', '')D os.path.Splitext() 返回(filename,extension) 元組
6]: os.path.splitext('/tmp/')
Out[86]: ('/tmp/', '')
A os.path.getatime() 返回文件最近一次的訪問記錄
B os.path.Getctime()
C os.path.Getmtime()
D os.path.Getsize() 返回文件的大小
A os.path.Exists() 判斷指定文件是否存在,檔不存在時,以只讀方式打開文件是錯誤的。
B os.path.Isabs() 判斷指定的路徑是不是絕對路徑
C os.path.isdir() 判斷指定路徑是否爲目錄
D os.path.Isfiel() 判斷指定文件是否爲文件
E os.path.Islink() 判斷時否爲符號連接
F os.patj.Ismount() 是否爲掛載點
G os.path.Sanefiek() 兩個路徑是否執行了同一個文件
簡介: 在內存中開闢一個文本模式的buffer,能夠像文件同樣操做它,當close方法被調用時,這個buffer被釋放,此處沒有持久化
1 StrinIO
#!/usr/local/bin/python3.6 #coding:utf-8 from io import StringIO sio=StringIO() sio.write("MySQL數據庫") print (sio.readline(),1) # 此處因爲指針在寫入時的緣由,致使指針指在了最後,所以致使其讀取不能完成 sio.seek(0) # 指針歸零 print (sio.readline(),2) # 進行讀取 print (sio.readline(),3) #因爲指針到最後,所以致使其不能讀取 print (sio.read(),4) #因爲指針到最後,所以致使其不能讀取 print (sio.getvalue(),5) # 此方法不會在意指針 sio.close() #文件關閉
查看顯示結果
優勢:通常來講,磁盤操做比內存慢,內存足夠的狀況下,通常的優化思路是減小落地,減小磁盤IO的過程,能夠大大提升程序的運行效率,單臺機器可使用StringIO,多臺設備之間使用redis來實現
2 BytesIO
#!/usr/local/bin/python3.6 #coding:utf-8 from io import BytesIO bio=BytesIO() bio.write("MYSQL數據庫".encode('utf-8')) # 寫入漢字須要指定編碼格式 print (bio.getvalue()) # 讀取數據,無論指針 bio.write(b'mysql database') bio.seek(0) print (bio.readline()) # 讀取一行 bio.seek(0) print (bio.read()) bio.close()
結果以下
3 file-like 對象
類文件對象,能夠像文件同樣操做
from sys import stdout f=stdout print (type(f)) f.write('51cto.com') #直接輸出到屏幕上
結果以下
3.4 版本開始,支持使用pathlib模塊提供對Path對象的操做,包括文件和目錄
p=Path() # 類初始化,初始化成實例
p.absolute() # 查看p的絕對路徑
p # 查看p的路徑,相對路徑
p=p.joinpath('/etc','a','b','c') # 此處第一個如有/表示絕對路徑,也表示從新建立路徑,若此處無/ 則表示在p的當前路徑下進行增長,及拼接
p=p /'c'/'d' # 對p進行增長路徑'c'/'d',也成爲路徑拼接
p1=Path('/a','b','/c') # 若指定多個絕對路徑,則之後面覆蓋前面的路徑
p1.parts # 返回一個元組,打印其跟和相對路徑
p1.parent # 返回當前路徑的父路徑
p1.parent.parent #返回當前父路徑的父路徑,依次類推,但若不存在則會報錯,所以不建議這樣使用
list(p1.parents) # 此處返回一個可迭代對象,可用for循環進行遍歷,並逐步取出其父路徑,其父路徑的父路徑,依次類推
list(p2.absolute().parents) # 對於相對路徑獲取其父路徑的方式
list(p2.absolute().parents)[0] # 獲取其父路徑
p3=Path('/etc/sysconfig/network/51.cfg')
p3.name # 獲取目錄的最後一部分,及51.cfg
p3.stem # 獲取目錄最後一部分的擴展名
p3.suffix # 獲取目錄最後一部分,沒有擴展名
p4=Path('/etc/sysconfig/network/51.cfg.gz')
p4.suffix # 獲取擴展名後綴 .gz
p4.suffixes # 返回多個擴展名列表 及 [.cfg,.gz]
p4=p4.with_suffix('.sz') # 修改擴展名後綴 結果爲 /etc/sysconfig/network/51.cfg.sz
p4=p4.with_name('52.cfg.gz') # 修更名字,結果以下 /etc/sysconfig/network/52.cfg.gz
p.iterdir()
列出該目錄下的文件,默認是一個生成器對象,其默認返回是一個PosixPath,其支持的方法有不少
l1[0].stat() 獲取文件的基本信息
此處有獲取其模式,硬連接,uid,gid,以及大小,日期等信息
此處有判斷其類型,有塊,字符,目錄,管道,文件,socket等,其返回是一個布爾類型
此處使用stat 可獲取如同Linux通常的權限列表
獲取屬主和屬組
要求 實現ls命令功能
1 實現顯示路徑下的文件列表
2 -a 和-all 顯示包含.開頭的文件
3 -l 顯示詳細列表信息
4 -h和 -l 配合,人性化顯示文件大小,如1k,1M,1G等
5 按照文件名排序輸出,能夠和ls的順序不一樣,但要求按照文件名進行排序
#!/usr/bin/poython3.6 #conding:utf-8 from pathlib import Path import datetime import stat import argparse def showDir(path:Path='.',all=False,lis=False,detailed=False): def _showSize(size:int): # 此處用於格式化文件大小 unit=" KMGTP" depth=0 while size>=1000: size=size //1000 depth+=1 return "{}{}".format(size,unit[depth]) def _showDir(path:Path='.',all=False,lis=False,detailed=False): p=Path(path) for file in p.iterdir(): if str(file.name).startswith('.') and not all:# 此處用於判斷文件是否須要列出隱藏文件 continue if lis: #此處用於判斷是否須要列出詳細信息 st=file.stat() # 此處返回一個文件詳細信息表 # -rw-r--r-- 1 root root 430 6月 3 14:02 char.py h=st.st_size if detailed: # 此處用於判斷是否 h=_showSize(st.st_size) yield (stat.filemode(st.st_mode),st.st_nlink,file.owner(),file.group(),h, datetime.datetime.fromtimestamp(st.st_atime).strftime("%Y-%m-%d %H:%M:%S"), file.name) else: yield file.name yield from sorted(_showDir(args.path,args.all,args.l,args.h),key=lambda x:x[-1]) # 此處用於對文件最後文件名進行排序 # 此處用於定義參數, parsent=argparse.ArgumentParser(prog='ls',description='list file',add_help=False) # prog表示提示usage爲ls,add_help爲False表示取消默認的-h顯示 parsent.add_argument('path',nargs='?',default='.',help="Incoming path information") #path 位置參數,nargs表示其參數的個數,'?'表示無關緊要,若無,則啓用默認參數 parsent.add_argument('-a','--all',action='store_true') # action='store_true' 此處若不填,則後面有大寫的選項參數 parsent.add_argument('-l',action='store_true',help='list file info') parsent.add_argument('-h',action='store_true',help='list file detailed') if __name__ == "__main__": args=parsent.parse_args(('/root','-lh')) for file in showDir(args.path,args.all,args.l,args.h): #此處的做用在於遍歷 print (file)
結果以下
csv 是一個被行分隔符,列分隔符劃分紅行和列的文本文件,沒有特定的字符編碼,可壓縮,大大節約空間
行分割符 \r \n ,最後一行能夠沒有換行符
列分割符經常用逗號或製表符進行處理
每一行成爲一個record
字段可使用雙括號括起來,也能夠不使用,若是字段中出現了雙引號,逗號,換行符必須使用雙引號括起來,若是字典中的值是雙引號,則使用功能兩個雙引號表示一個轉義
reader(csvfile,dialect='excel',**fmtparams) # 返回DictReader 的實例,是個行迭代器
delimiter #列分割符 逗號
lineterminator # 行分割符 \r\n
quotechar # 字段的引用符號,缺省爲雙引號
雙引號的處理:
doublequote 雙引號的處理,默認爲True,若是和quotechar爲同一個,True則使用2個雙引號表示,False表示轉義字符將做爲雙引號的前綴
escapechar 一個轉義字符,默認爲None
quoting 指定雙引號的規則,QUOTE_ALL 全部字段,QUOTE_MINIMAL 特殊字符字段
QUOTE_NONNUMERIC非數字字段,QUOTE_NONE 都不使用引號。writer(csvfile,dialect='excel',**fmtparams)
返回DictWriter的實例
主要方法有writerow,writerows
#!/usr/local/bin/python3.6 #coding:utf-8 from pathlib import Path import csv p=Path('/root/test.csv') if not p.parent.exists(): # 判斷其父路徑是否存在,若不存在,則建立 p.parent.mkdir(parents=True) #建立其父路徑 line1=[1,2,3,4,576] with open(p,'w') as f: writer=csv.writer(f) #寫入文件系統 writer.writerow(line1) #進行寫入一行操做
結果以下
#!/usr/local/bin/python3.6 #coding:utf-8 from pathlib import Path import csv p=Path('/root/test.csv') if not p.parent.exists(): # 判斷其父路徑是否存在,若不存在,則建立 p.parent.mkdir(parents=True) #建立其父路徑 line1=[1,2,3,4,576] line2=[10,22,'3',40,'576'] with open(p,'w') as f: writer=csv.writer(f) #寫入文件系統 writer.writerow(line1) #進行寫入一行操做 writer.writerow(line2) #寫入下一行操做
寫入結果以下
同時寫入多行
#!/usr/local/bin/python3.6 #coding:utf-8 from pathlib import Path import csv p=Path('/root/test.csv') if not p.parent.exists(): # 判斷其父路徑是否存在,若不存在,則建立 p.parent.mkdir(parents=True) #建立其父路徑 line1=[1,2,3,4,576] line2=[10,22,'3',40,'576'] line3=[line1,line2] with open(p,'w') as f: writer=csv.writer(f) #寫入文件系統 writer.writerow(line1) #進行寫入一行操做 writer.writerow(line2) #寫入下一行操做 writer.writerows(line3) #同時寫入多行操做
結果以下
讀取操做
#!/usr/local/bin/python3.6 #coding:utf-8 from pathlib import Path import csv p=Path('/root/test.csv') if not p.parent.exists(): # 判斷其父路徑是否存在,若不存在,則建立 p.parent.mkdir(parents=True) #建立其父路徑 line1=[1,2,3,4,576] line2=[10,22,'3',40,'576'] line3=[line1,line2] with open(p,'w') as f: writer=csv.writer(f) #寫入文件系統 writer.writerow(line1) #進行寫入一行操做 writer.writerow(line2) #寫入下一行操做 writer.writerows(line3) #同時寫入多行操做 with open(p) as f: reader=csv.reader(f) #因爲其返回的是一個迭代器,所以可經過for循環方式進行讀取操做 for line in reader: if line: #判斷讀取到的行是否存在 print (line)
結果以下
Dictreader 和 DictWriter 對象
使用 dictreader能夠向操做字典那樣獲取數據,把表的第一行(通常是表頭)做爲key,可訪問每一行中的那個key對應的數據
#!/usr/local/bin/python3.6 #coding:utf-8 import itertools import pymysql import csv filename='/root/test1.csv' with open(filename) as f: reader=csv.DictReader(f) for row in reader: max_tmp=row['passwd'],row['name'],row['createtime'] print (max_tmp)
結果以下
DictWriter 類,能夠寫入的字典形式的數據,一樣鍵也是表頭
#!/usr/local/bin/python3.6 #coding:utf-8 import csv headers=['name','age'] datas=[ {'name':'zhang1','age':25}, {'name': 'zhang2', 'age': 26}, {'name': 'zhang3', 'age': 27}, ] with open('/root/test2.csv','w+') as f: writer=csv.DictWriter(f,headers) # 寫入表的形式 writer.writeheader() # 寫入表頭數據 for row in datas: writer.writerow(row) # 寫入真實數據,逐條寫入 writer.writerows(datas) # 寫入真實數據,一次性寫入
結果以下
.ini 文件時initalization file 的縮寫,及就是初始化文件,是windows的系統配置文件所採用的存儲格式,統一管理Windows的各項配置,通常用戶就用Windows提供的各項圖形化管理工具變可實現相同配置,現在的mysql依然採用這種方式實現配置文件的初始化操做。
格式
INI 文件由節(區域),鍵,值組成
節及就是 section 其中是由key=value的形式保存,key成爲option選項
configparser 模塊的ConfigParser類就是用來操做的
方法
read(filenames,encoding=None)
讀取ini文件,能夠是單個文件,也能夠是文件列表,能夠指定文件編碼
optons(section) 返回section下的全部option
get(section,option,*,raw=False,vars=None[,fallback])
從指定的段的選項上取值,若是找到則返回,若是沒找到,則取DEFAULT段中查找
getint(section,option,*,raw=False,vars=None[,fallback])
從指定的字段選項上取值,返回×××,至關於作了int() 進行轉型,默認是str字符串類型
getfloat(section,option,*,raw=False,vars=None[,fallback])
同上
getboolean(section,option,*,raw=False,vars=None[,fallback])
同上 布爾類型
items(raw=False,vars=None) #對全部進行遍歷,返回鍵值對,不指定段,默認返回全部段中的key和value的值,若中途存在相同的key=value再不一樣的段中出現,則可能發生衝突,建議使用下面的方式進行處理
items(section,raw=False,vars=None) # 指定返回段的key和value
sections()返回section列表,缺省section不包括在內[DEFAULT]
has_section(section_name) 判斷section是否存在
has_option(section,option) 判斷section 是否存在這個option
add_section(section_name) 增長一個section
set(section,option,value)#section 存在的狀況下,寫入option=value,要求option,value 必須是字符串
remove_section(section) #移除section及其全部的option
remove_option(section,option) # 移除section下的option
write(fileobject,space_around_delimiters=True) # 將當前config的全部內容寫入到flieobject中,一盤open函數使用w模式。
1 基本讀取
#!/usr/local/bin/python3.6 #coding:utf-8 from configparser import ConfigParser cfg=ConfigParser() # 初始化操做 cfg.read('/etc/my.cnf') # 讀取文件內容 print (cfg.sections()) # 打印其區,並返回列表 for sections in cfg.sections(): #遍歷section for opt in cfg.options(sections): # 遍歷其中的值 print (sections,opt) # 打印section和option for i in cfg.items('mysqld'): #指定section,返回其下面的key和value,以元組的方式返回 print (i)
結果以下
2 寫入和移除
#!/usr/local/bin/python3.6 #coding:utf-8 from configparser import ConfigParser from pathlib import Path p=Path('/root/my.cnf') # 定義一個文件 parent=p.parent # 獲取其父目錄 if not parent.exists(): # 判斷其父目錄是否存在。若不存在則建立 parent.mkdir(parent=True) with open(p,'w+') as f: # 以寫的方式建立父目錄 f.write("") cfg=ConfigParser() # 定義初始化 cfg.read('/root/my.cnf') # 定義讀取 if not cfg.has_section('test'): # 查看section是否存在,若不存在,則建立 cfg.add_section('test') if not cfg.has_option('test','test1'): #查看test下的test1是否存在,若不存在,則建立 cfg.set('test','test1','2')#其value必須是字符串 with open(p, 'w') as f: cfg.write(f) # 將數據持久化存儲至文件中 print (cfg.items('test')) # 查看 print (type(cfg.get('test','test1')),cfg.get('test','test1')) # 獲取key對應的value print (type(cfg.getint('test','test1')),cfg.getint('test','test1')+1) # 獲取key對應的value,並以×××輸出 cfg.remove_option('test','test1') #移除其中的key和value print (cfg.sections()) cfg.remove_section('test') #移除這個段 print (cfg.sections())
查看結果