1.哈希 hashpython
在將文件操做的方法以前,咱們先來對上節的知識作一個拓展,就是哈希算法,那麼什麼是哈希算法呢?算法
(1)哈希:hash,通常翻譯作散列、雜湊,或音譯爲哈希,是把任意長度的輸入(又叫作預映射pre-image)經過散列算法變換成固定長度的輸出,該輸出就是散列值。數據庫
這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間。函數
哈希算法的輸入能夠是字符串,能夠是數據,能夠是任何文件,通過哈希運算後,都變成一個固定長度的輸出,該輸出就是哈希值。區塊鏈
>>> hash('我愛你') 3471388576844338423 >>> hash('小猿圈') 5000768010434506639
如上所示,輸入「我愛你」三個字,通過哈希運算後,會獲得一個隨機數列,並且無論你的輸入文件多大,最後獲得的結果都是這麼一個固定長度的數列,即便你輸入的是一部電影,輸出也是這麼大。編碼
(2)特性:加密
1.不可逆性:在具有編碼功能的同時,哈希算法也做爲一種加密算法存在。即,你沒法經過分析哈希值計算出源文件的樣子。spa
不管是什麼形式,任意大小的輸入,最終結果都是一串長度相等的隨機數列,所以你沒法經過哈希值來推斷數據本來的樣子。翻譯
2.計算極快:不管是一個5G的電影仍是一個5k的文件,運用哈希算法計算量都極小,很快就能夠計算出哈希值。code
(3)用途:
哈希算法的不可逆特性使其在如下領域使用普遍
-
密碼,咱們平常使用的各類電子密碼本質上都是基於hash的,你不用擔憂支付寶的工做人員會把你的密碼泄漏給第三方,由於你的登陸密碼是先通過 hash+各類複雜算法得出密文後 再存進支付寶的數據庫裏的
-
文件完整性校驗,經過對文件進行hash,得出一段hash值 ,這樣文件內容之後被修改了,hash值就會變。 MD5 Hash算法的」數字指紋」特性,使它成爲應用最普遍的一種文件完整性校驗和(Checksum)算法,很多Unix系統有提供計算md5 checksum的命令。
-
數字簽名,數字簽名技術是將摘要信息用發送者的私鑰加密,與原文一塊兒傳送給接收者。接收者只有用發送者的公鑰才能解密被加密的摘要信息,而後用HASH函數對收到的原文產生一個摘要信息,與解密的摘要信息對比。若是相同,則說明收到的信息是完整的,在傳輸過程當中沒有被修改,不然說明信息被修改過,所以數字簽名可以驗證信息的完整性。
此外,hash算法在區塊鏈領域也使用普遍。
(4)在Python中基於HASH的數據類型是dict (字典)和set (集合)。以前說到的字典查詢速度極快,以及集合天生去重就是運用了hash的特性。如下能夠做一下了解。
1.dict查詢速度快
假設一個dict中有不少信息,dict會將每個key進行哈希,將全部的哈希值按照從大到小的順序放到一個列表中,如keys=[ -22,-10,11,23,99]
當須要查找某個信息時,dict將被查找信息的key進行哈希,同一個輸入值進行哈希獲得的哈希值時相等的,所以只需再列表中找到這個哈希值,就能找到對應的value。
那麼問題來了,若是字典的數據比較小,計算機就能很快找到對應的值,可是若是字典中有幾十億條數據,怎麼快速的找到對應的值呢?
dict採用的是二分法查找,即將被查找信息的key的哈希值與列表的中間的值比較大小,這樣就能夠捨棄一半的值,這樣搜索區間就小了不少,多進行幾回這樣的操做,很快就能夠找到對應的值。
這就是字典爲什麼查詢速度快的基本原理,固然真實的算法會複雜的多。
2.set 天生去重
由於每存一個值到set裏時, 都要先通過hash,而後經過得出的這個hash值算出應該存在set裏的哪一個位置,存的時候會先檢查那個位置上有沒有值 ,
有的話就對比是否相等,若是相等,則再也不存儲此值。 若是不相等(即爲空),則把新值存在這。
2.文件操做
Python的文件操做基本經過如下步驟
f = open(filename) # 打開文件
f.write("hello world") # 寫操做
f.read( ) # 讀操做
f.close( ) # 保存並關閉文件
經常使用操做模式
python文件有三種基本的操做模式
r 只讀模式
w 建立模式,不能讀,用此模式操做,新的內容會覆蓋舊的內容。即清空原來的內容,寫入新的內容。
a 追加模式 ,寫入的內容會追加到文件最後
只讀模式
f = open('filename.text', 'r') f.readline() # 讀一行內容 content = f.read() # 讀全部剩下的內容 print(content) f.close()
建立模式
f = open('filename.text', 'w') f.write('hello world') # 此時該文件的內容爲hello world(無論原文件內容是什麼) f.close()
追加模式
f = open('filename.text', 'a') f.write("小猿圈") # 此時文件內容爲 hello world小猿圈 f.close()
循環文件
f = open('filename.tesxt' , 'r') for line in f: # 遍歷文件的每一行 print(line)
文件的其餘操做功能
f = open('filename.text', 'r') f.mode # 返回文件的打開方式 f.name # 返回文件名 f.fileno() # 返回文件句柄在內核中的索引值,之後作IO多路複用時能夠用到 f.flush() #將內容寫入硬盤時,因爲硬盤的處理速度慢,內容會先在內存中,達到必定數量一# 起寫入硬盤提高效率,flush()方法可將內存中的數據寫入硬盤 f.readable() # 判斷文件是否可讀 f.readline() # 只讀一行,遇到\r 或 \n爲止 f.seek() # 把操做文件的光標移動到指定位置 seek的長度是按字節算的 不一樣的編碼方式每 #個字符所佔的字節不一樣。如gbk編碼下中文字符佔兩個字節,utf-8編碼下中文字符佔三個字 #節,若是讀取文件時的編碼方式不一樣會致使錯誤產生。 f.seekable() # 判斷文件是否能進行 seek 操做 f.tell() # 返回當前文件操做光標的位置 f.truncate() # 按指定長度截取文件 # 指定長度的話,就從文件開頭開始截斷指定長度; # 不指定長度的話,就從光標當前位置到文件 # 尾部的內容全去掉。 f.writeable() # 判斷文件是否可寫
混合模式
文件打開還有三種混合模式,既能夠讀也能夠寫。
w+ 寫讀 ,它會建立一個新文件 ,寫一段內容,能夠再把寫的內容讀出來,通常不用。
r+ 讀寫,能讀能寫,但都是寫在文件最後,跟追加同樣,用的較多。
a+ 追加讀,文件一打開時光標會在文件尾部,寫的數據全會是追加的形式。
w+模式
f=open('filename.text','w+') # w+讀取時 光標在最後一行 讀取時須要指定光標 f.write("alex 23 male") f.seek(0) # 將光標移至開頭 再讀取 print(f.readline()) f.close()
r+模式
f = open('filename', 'r+') f.write() # 默認往文件尾部寫 f.readline() # 讀的是第一行
r+模式會將內容自動往文件末尾寫,可是若是想修改數據應該怎麼辦?
將光標移動到中間的某一個位置,插入一個信息,會發現原來的信息會被寫入的信息所覆蓋。緣由是,當你將文件存到硬盤上時,就在硬盤上劃分了一段空間,空間就那麼大,當你想寫入新的內容時,就只能覆蓋掉原來的數據,而不能使數據總體向後移。
若是想要修改文件,就只能將文件加載到內存當中,數據在內存當中能夠隨便增刪改查,以後再將修改完的數據存入硬盤覆蓋掉原來的數據,就完成了文件的修改。
注:r+使用時,該文件必須存在。
當你想修改一份特別大的文件的時候,一下把文件加載到內存,是一種不明智的方式。若是想不佔內存,能夠採用一邊讀一邊寫的方式,就是建立一個新的文件,一邊從原文件中讀,一邊寫入新的文件。
f_name = "filename.txt" f_new_name = "%s.new" % f_name old_str = "eric" new_str = "alex" f = open(f_name,'r') # 打開原文件 f_new = open(f_new_name,'w') # 建立一個新文件 for line in f: # 讀原文件 if old_str in line: new_line = line.replace(old_str,new_str) # 修改文件 else: new_line = line f_new.write(new_line) 寫入新文件 f.close() f_new.close()
注:以上內容部分參考自路飛學城。