Python回顧與整理7:文件和輸入輸出

0.說明python

        

        主要是下面的內容:
程序員

  • 文件對象:內建函數、內建方法、屬性json

  • 標準文件bash

  • 文件系統:訪問方法、文件執行數據結構

  • 持久化存儲ide

  • 標準庫中與文件有關的模塊函數




1.文件對象測試


        文件對象是用來訪問文件的接口,而文件只是連續的字節序列,數據的傳輸常常會用到字節流,不管字節流是由單個字節仍是大塊數據組成。
編碼




2.文件內建函數(open()和file())spa


        內建函數open()以及file()提供了初始化輸入/輸出(I/O)操做的通用接口,若是打開文件成功,則會返回一個文件對象,不然會引起IOError異常,open()和file()並無任何區別,能夠任意替換,基本語法以下:

file_object = open(file_name, access_mode='r', buffering=-1)

        說明以下:

  • file_name:包含要打開的文件名的字符串表示,能夠是相對路徑或絕對路徑

  • access_mode:訪問模式,可選參數,若是沒有指定,默認值爲'r'(字符串表示)

        訪問模式主要有下面幾種:

模式 說明
'r' 讀取,文件必需要存在
'w' 寫入,文件存在則清空原來文件內容再寫入;文件不存在則自動建立該文件並寫入內容
'a' 追加,文件存在只會在文件後面追加數據;文件不存在則自動建立該文件並寫入內容
'+' 表示可讀可寫,但不能單獨使用,通常與'r'一塊兒使用
'b'

以二進制模式訪問文件,但不能做爲第一個字符出現,對於Unix系統來講,可能會被忽略掉,由於Unix系統默認把全部文件看成進制文件,因此使用'b'模式時,通常是但願在全部系統平臺上都是用二進制模式來訪問文件(好比在Windows上)

'U'

通用換行符支持(UNS),用來處理不一樣操做系統平臺上的換行符(\n,\r或者\r\n),使用該模式時,文件對象的newlines屬性會記錄它曾「看到的」文件的行結束符,文件剛打開時,程序尚未遇到換行符,newlines值爲None,在文件第一行被讀取後,它被設置爲第一行的結束符,若是遇到其餘類型的行結束符,newlines會成爲一個包含每種格式的元組。

不過須要注意的是,UNS中用於讀取文本文件,沒有對應的處理文件輸出的方法。默認狀況下該模式是打開的,若是不須要,能夠在執行腳本文件時使用參數--without-universal-newlines

        經常使用的訪問模式組合以下:

文件對象的訪問模式
文件模式 操做
r 以讀方式打開
rU或U 以讀方式打開,同時提供通用換行符支持
w 以寫方式打開(必要時清空)
a 以追加模式打開(從EOF開始,必要時建立新文件)
r+ 以讀寫模式打開
w+ 以讀寫模式打開(參見w)
a+ 以讀寫模式打開(參見a)
rb 以二進制讀模式打開
wb 以二進制寫模式打開(參見w)
ab 以二進制追加模式打開(參見a)
rb+ 以二進制讀寫模式打開(參見r+)
wb+ 以二進制讀寫模式打開(參見w+)
ab+ 以二進制讀寫模式打開(參見a+)
  • buffering:用於指示訪問文件所採用的緩衝方式,採用默認方式便可

        0表示不緩衝,1表示緩衝一行數據,任何其餘大於1的值表明使用給定值做爲緩衝區大小。

        



3.文件內建方法


        open()成功執行後會返回一個文件對象,對該文件的全部操做都經過這個句柄來完成,其操做方法以下:


(1)輸入

        主要以下:

  • read(size=-1):讀取給定數目個字節並以字符串返回,size默認爲-1或其餘負值時,表示所有讀取

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f = open('test.txt', 'r')
>>> f.read()
'xpleafclyyh\ncl\n'
>>> f = open('test.txt', 'r')
>>> f.read(6)
'xpleaf'
>>> f.close()
  • readline(size=-1):讀取文件的一行並以字符串返回,size默認爲-1或其餘負值時,表示所有讀取,給定size值時,若是小於當前行的字節數,則不完整地讀取一行,不然則會完整讀取該行

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f = open('test.txt', 'r')
>>> f.readline()
'xpleafclyyh\n'
>>> f = open('test.txt', 'r')
>>> f.readline(6)
'xpleaf'
>>> f.readline(10)
'clyyh\n'
>>> f.close()
  • readlines([size]):以列表的方式返回全部的行,不過在測試時size參數沒有起做用

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f.close()

        另外還有一個xreadlines()的方法,能夠不用所有讀取全部的行以節省空間,不過因爲如今文件讀取可使用for循環迭代的方式,即for eachLine in file,因此能夠不使用xreadlines()便可以節省內存空間。

        在讀取操做時能夠看到,Pytthon不會自動爲咱們去掉換行符,因此通常咱們這樣處理:

f = open('myFile', 'r')
data = [line.strip() for line in f.readlines()]
f.close()

        一樣,在下面的輸出中,Python也不會自動爲咱們加上換行符,這個操做要咱們本身完成。


(2)輸出

        主要以下:

  • write(str):把數據寫入到文件中,須要寫入一行數據時能夠在字符串後面加行結束符便可,因此輸出的方法並無writeline()

>>> f = open('test.txt', 'w')
>>> f.write('xpleaf')
>>> f.write('clyyh\n')
>>> f.write('cl\n')
>>> f.close()
>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f.close()
  • writelines(seq):接受一個字符串列表做爲參數,將它們寫入文件,不過行結束符並不會被自動加上

>>> f = open('test.txt', 'w')
>>> data = ['xpleaf', 'test\n', 'clyyh\n']
>>> f.writelines(data)
>>> f.close()
>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleaftest\n', 'clyyh\n']
>>> f.close()


(3)文件內移動

        主要是下面的兩個方法:

  • seek(offset[, whence]):移動文件指針到不一樣的位置,offset字節表示相對於位置whence的偏移量,whence的默認值爲0,表示相對於文件的開頭,1表明從當前位置算起,2表明從文件末尾算起

  • tell():返回當前文件指針所在的位置

        舉例以下:

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f.seek(0)
>>> f.read(6)
'xpleaf'
>>> f.tell()
6
>>> f.seek(8)
>>> f.tell()
8
>>> f.read()
'yyh\ncl\n'
>>> f.tell()
15
>>> f.seek(-3, 1)
>>> f.tell()
12
>>> f.read()
'cl\n'
>>> f.seek(0)
>>> f.tell()
0
>>> f.seek(-3, 2)
>>> f.tell()
12
>>> f.read()
'cl\n'
>>> f.close()


(4)文件迭代

        在Python2.2以後,引進了迭代器和文件迭代,文件對象成爲了它們本身的迭代器,所以能夠經過使用for循環迭代(for line in file)的方式來取代xreadlines()的功能,這樣的話就能夠大大節省內存空間。由於文件對象自己就是一個迭代器,因此它有next()方法,而且在迭代完全部數據後會引起StopIteration異常。


(5)其餘

        其餘內建方法以下:

  • close():經過關閉文件來結束對它的訪問,若是不顯式地關閉文件,那麼可能丟失輸出緩衝區的數據

  • flush():直接把內部緩衝區中的數據馬上寫入文件

        在執行f.write()的操做時,其實並無把內容實時地寫入到磁盤中,而是保存到內部緩衝區中,在文件關閉或執行flush()時都會保存在磁盤中。

  • flieno():返回打開文件的描述符

>>> f = open('welcome.txt', 'r')
>>> f.fileno()
3
  • isatty():當文件是一個類tty設備時返回True,不然返回False

  • truncate([size]):將文件截取到當前文件指針位置或者到給定size,以字節爲單位

        所謂的截取其實就是把當前位置以後的文件內容刪除,給定了size參數,代表從第幾個字節開始截取(包括該字節),若是size沒有給定,則默認從當前位置開始,以下:

>>> f = open('test.txt', 'r+')
>>> f.read()
'clyyh'
>>> f.truncate()
>>> f.seek(0)
>>> f.read()
'clyyh'
>>> f.truncate(2)
>>> f.seek(0)
>>> f.read()
'cl'


(6)行分隔符與路徑分隔符在不一樣操做系統中的差別

        以下:

  • 行分隔符:在POSIX(Unix系列或Mac OX X)系統上是'\n'字符,在舊的MacOS下是'\r',而DOS和Wind32系統下結合了二者'\r\n'

  • 路徑分隔符:POSIX使用'/',DOS和Windows使用'\',舊版本的MacOS使用':'

        若是要建立跨平臺的應用時,就須要處理這些差別,不過Python中的os模塊已經有相關屬性來爲咱們處理這些差別:

有助於跨平臺開發的os模塊屬性
os模塊屬性 描述
linesep 用於在文件中分隔行的字符串
sep 用來分隔文件路徑名的字符串
pathsep 用於分隔文件路徑的字符串
curdir 當前工做目錄的字符串名稱
pardir (當前工做目錄的)父目錄字符串名稱

        下面是在Linux操做系統上的例子:

>>> import os
>>> os.linesep
'\n'
>>> os.sep
'/'
>>> os.pathsep
':'
>>> os.curdir
'.'
>>> os.pardir
'..'

        下面是在Windows操做系統上的例子:

>>> import os
>>> os.linesep
'\r\n'
>>> os.sep
'\\'
>>> os.pathsep
';'
>>> os.curdir
'.'
>>> os.pardir
'..'

        不過另外須要注意的是,print語句在輸出時會自動爲咱們添加一個換行符,若是不須要該換行符,能夠在輸出語句後面加一個逗號','。




4.文件內建屬性


        主要以下:

文件對象的屬性
屬性 描述
flie.closed 若是文件已經關閉返回True,不然返回False
file.encoding 文件所使用的編碼——當Unicode字符串被寫入數據時,它們將自動使用file.encoding轉換爲字節字符串;若file.encoding爲None時使用系統默認編碼
file.mode 文件打開時使用的訪問模式
file.name

文件名

file.newlines 未讀取到行分隔符時爲None, 只有一種行分隔符時爲一個字符串,當文件有多種類型的行結束符時,則爲一個包含全部當前所遇到的行結束符的列表
file.softspace 爲0表示在輸出一數據後,要加上一個空格符,1表示不加。這個屬性通常程序員用不着,由程序內部使用

        舉例以下:

>>> f = open('test.txt', 'r+')
>>> f.read()
'xpleaf\nclyyh\ncl'
>>> f.closed
False
>>> f.encoding
>>> f.mode
'r+'
>>> f.name
'test.txt'
>>> f.newlines
>>> f.softspace
0

        可是能夠看到的是,newlines並無任何輸出。




5.標準文件


        只要Python程序一執行,其實就能夠訪問到下面的這三個標準文件:

  • 標準輸入:鍵盤或磁盤的輸入

  • 標準輸出:到顯示器的緩衝輸出

  • 標準錯誤:到屏幕的非緩衝輸出

        注意上面的緩衝指的是open()的第三個參數,而之因此說程序一執行就能夠訪問這3個標準文件,是由於這些文件預先已經被打開了,只要知道它們的文件句柄主能夠隨時訪問這些文件,Python中能夠經過sys模塊來訪問這些文件的句柄:

  • sys.stdin

  • sys.stdout

  • sys.stderr

        print語句一般是輸出到sysy.stdout,而raw_input()則一般是從sys.stdin接收輸入,以下:

>>> import sys
>>> sys.stdout.write('xpleaf\n')
xpleaf
>>> sys.stdin.readline()
xpleaf
'xpleaf\n'

        其實上面的三個模塊的屬性也是file文件類型:

>>> for stream in [sys.stdin, sys.stdout, sys.stderr]:
...   print type(stream)
... 
<type 'file'>
<type 'file'>
<type 'file'>




6.命令行參數


        在C語言中有argc和argv兩個變量,分別表明參數個數和參數向量,在Python中,argc其實就是sys.argv列表的長度,而該列表的第一項sys.argv[0]永遠是程序的名稱。舉例以下:

        程序代碼:

#!/usr/bin/env python

import sys

print 'you entered', len(sys.argv), 'arguments...'
print 'they were', str(sys.argv)

        執行結果:

xpleaf@leaf:~$ python argv.py xpleaf clyyh cl
you entered 4 arguments...
they were ['argv.py', 'xpleaf', 'clyyh', 'cl']

        PYthon中關於命令行參數處理的模塊以下:

  • getopt模塊:不是很精細,可是簡單

  • optparse模塊:功能強大,更面向對象




7.文件系統


        Python對文件系統的訪問經過os模塊實現,該模塊是Python訪問操做系統功能的主要接口,但不是真正的接口,真正的接口是由操做系統提供的,因此能夠有以下的關係:

Python程序—os模塊—操做系統文件系統接口模塊(由os模塊根據不一樣的操做系統進行選擇)

        而最經常使用的是os和os.path,這兩個模塊提供了與平臺和操做系統無關的統一文件系統訪問方法,以下:

  • os模塊

os模塊的文件/目錄訪問函數
函數 描述
文件處理
mkfifo()/mknod() 建立命名管道/建立文件系統節點
remove()/unlink() 刪除文件
rename()/renames() 重命名文件
stat(),lstat(),xstat() 返回文件信息
symlink() 建立符號連接
utime() 更新時間戳
tmpfile() 建立並打開('w+b')一個新的臨時文件
目錄/文件夾
chdir()/fchdir() 改變當前工做目錄/經過一個文件描述符改變當前工做目錄
chroot() 改變當前進程的根目錄
listdir() 列出指定目錄的文件
getcwd()/getcwdu() 返回當前工做目錄/功能相同,但返回一個Unicode對象
mkdir()/makedirs() 建立目錄/建立多層目錄
rmdir()/removedirs() 刪除目錄/刪除多層目錄
訪問/權限
access() 檢驗權限模式
chmod() 改變權限模式
chown()/lchown() 改變owner和group ID/功能相同,但不會跟蹤連接
umask() 設置默認權限模式
文件描述符操做
open() 底層的操做系統open(對於文件,使用標準的內建open()函數)
read()/write() 根據文件描述符讀取/寫入數據
dup()/dup2() 複製文件描述符號/功能相同,可是是複製到另外一個文件描述符
設備號
makedev() 從major和minor設備號建立一個原始設備號
major()/minor() 從原始設備號得到major/minior設備號
  • os.path模塊

os.path模塊中的路徑名訪問函數
函數 描述
分隔
basename() 去掉目錄路徑,返回文件名
dirname() 去年文件名,返回目錄路徑
join() 將分離的各部分組合成一個路徑名
split() 返回(dirname(), basename())元組
splitdrive() 返回(dirname, pathname)元組
splitext() 返回(filename, extension)元組
信息
getatime() 返回最近訪問時間
getctime() 返回文件建立時間
getmtime() 返回最近文件修改時間
getsize() 返回文件大小(以字節爲單位)
查詢
exists() 指定路徑(文件或目錄)是否存在
isabs() 指定路徑是否爲絕對路徑
isdir() 指定路徑是否存在且爲一個目錄
isfile() 指定路徑是否存在且爲一個文件
islink() 指定路徑是否存在且爲一個符號連接
ismount() 指定路徑是否存在且爲一個掛載點
samefile() 兩個路徑名是否指向同一個文件


        關於os和os.path,一個經典的例子以下:

#!/usr/bin/env python

import os
for tmpdir in ('/tmp', r'c:\temp'):
    if os.path.isdir(tmpdir):
        break
else:
    print 'no temp directory available'
    tmpdir = ''

if tmpdir:
    os.chdir(tmpdir)
    cwd = os.getcwd()
    print '*** current temporary directory'
    print cwd

    print '*** creating example directory...'
    os.mkdir('example')
    os.chdir('example')
    cwd = os.getcwd()
    print '*** new working directory: '
    print cwd
    print '*** original directory listing: '
    print os.listdir(cwd)

    print '*** creating test file...'
    fobj = open('test', 'w')
    fobj.write('foo\n')
    fobj.write('bar\n')
    fobj.close()
    print '*** updated directory listing: '
    print os.listdir(cwd)

    print "*** renaming 'test' to 'filetest.txt' "
    os.rename('test', 'filetest.txt')
    print '*** updated directory listing: '
    print os.listdir(cwd)

    path = os.path.join(cwd, os.listdir(cwd)[0])
    print '*** full file pathname'
    print path
    print '*** (pathname, basename) =='
    print os.path.split(path)
    print '*** (filename, extension) =='
    print os.path.splitext(os.path.basename(path))

    print '*** displaying file contents: '
    fobj = open(path)
    for eachLine in fobj:
        print eachLine,
    fobj.close()

    print '*** deleting test file'
    os.remove(path)
    print '*** updated directory listing: '
    print os.listdir(cwd)
    os.chdir(os.pardir)
    print '***  deleting test directory'
    os.rmdir('example')
    print '*** DONE'

        在Linux操做系統執行以下:

xpleaf@leaf:~$ python ospathex.py 
*** current temporary directory
/tmp
*** creating example directory...
*** new working directory: 
/tmp/example
*** original directory listing: 
[]
*** creating test file...
*** updated directory listing: 
['test']
*** renaming 'test' to 'filetest.txt' 
*** updated directory listing: 
['filetest.txt']
*** full file pathname
/tmp/example/filetest.txt
*** (pathname, basename) ==
('/tmp/example', 'filetest.txt')
*** (filename, extension) ==
('filetest', '.txt')
*** displaying file contents: 
foo
bar
*** deleting test file
*** updated directory listing: 
[]
***  deleting test directory
*** DONE

        在Windows操做系統上執行以下:

C:\Users\xpleaf\Source_code>python ospathex.py
*** current temporary directory
c:\temp
*** creating example directory...
*** new working directory:
c:\temp\example
*** original directory listing:
[]
*** creating test file...
*** updated directory listing:
['test']
*** renaming 'test' to 'filetest.txt'
*** updated directory listing:
['filetest.txt']
*** full file pathname
c:\temp\example\filetest.txt
*** (pathname, basename) ==
('c:\\temp\\example', 'filetest.txt')
*** (filename, extension) ==
('filetest', '.txt')
*** displaying file contents:
foo
bar
*** deleting test file
*** updated directory listing:
[]
***  deleting test directory
*** DONE




8.文件執行


        關於如何啓動其餘程序,以及如何與它們進行通訊,或者是Python執行環境的通常信息,能夠參考《Python回顧與整理12:執行環境》。




9.永久存儲模塊


        以二進制數據的形式來存儲Python的複雜數據結構(如列表、字典等),主要是pickle和json,其它的在須要用到時查閱便可。




10.相關模塊


        在須要使用時查閱便可。

相關文章
相關標籤/搜索