1、文件操做

      打開文件時,須要指定文件路徑和以何等方式打開文件,打開後,便可獲取該文件句柄,往後經過此文件句柄對該文件操做。html

打開文件的模式有:java

  • r ,只讀模式【默認模式,文件必須存在,不存在則拋出異常】(不加mode時默認爲r模式)
  • w,只寫模式【不可讀;不存在則建立;存在則清空內容】(至關於從新建立了文件)
  • x, 只寫模式【不可讀;不存在則建立,存在則報錯】
  • a, 追加模式【不可讀;   不存在則建立;存在則只追加內容】

"+" 表示能夠同時讀寫某個文件python

  • r+, 讀寫【可讀,可寫】
  • w+,寫讀【可讀,可寫】
  • x+ ,寫讀【可讀,可寫】
  • a+, 寫讀【可讀,可寫】

"U"表示在讀取時,能夠將 \r \n \r\n自動轉換成 \n (與 r 或 r+ 模式同使用)sql

  • rU
  • r+U

 "b"表示以字節的方式操做數據庫

  • rb  或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

 注:以b方式打開時,讀取到的內容是字節類型,寫入時也須要提供字節類型,不能指定編碼express

文件操做各類方法詳解

方法 描述
f.close() 關閉文件,記住用open()打開文件後必定要記得關閉它,不然會佔用系統的可打開文件句柄數。
f.fileno() 得到文件描述符,是一個數字
f.flush() 刷新輸出緩存
f.isatty() 若是文件是一個交互終端,則返回True,不然返回False。
f.read([count]) 默認讀出所有文件,若是有count,則讀出count個字符。
f.readline() 讀出一行信息。
f.readlines() 讀出全部行,也就是讀出整個文件的信息。
f.seek(offset[,where]) 把文件指針移動到相對於where的offset位置。where爲0表示文件開始處,這是默認值 ;1表示當前位置;2表示文件結尾。
f.seekable() 判斷光標是否可移動,像tty文件或終端設備文件光標不可移動
f.tell() 得到文件指針位置。
f.truncate([size]) 截取文件,使文件的大小爲size。
f.write(string) 把string字符串寫入文件。
f.writelines(list) 把list中的字符串一行一行地寫入文件,是連續寫入文件,沒有換行。

示例文件windows

Somehow, it seems the love I knew was always the most destructive kind
不知爲什麼,我經歷的愛情老是最具毀滅性的的那種
Yesterday when I was young
昨日當我年少輕狂
The taste of life was sweet
生命的滋味是甜的
As rain upon my tongue
就如舌尖上的雨露
I teased at life as if it were a foolish game
我戲弄生命 視其爲愚蠢的遊戲
The way the evening breeze
就如夜晚的微風
May tease the candle flame
逗弄蠟燭的火苗
The thousand dreams I dreamed
我曾千萬次夢見
The splendid things I planned
那些我計劃的絢麗藍圖
I always built to last on weak and shifting sand
但我老是將之建築在易逝的流沙上
I lived by night and shunned the naked light of day
我夜夜笙歌 逃避白晝赤裸的陽光
And only now I see how the time ran away
事到現在我纔看清歲月是如何匆匆流逝
Yesterday when I was young
昨日當我年少輕狂
So many lovely songs were waiting to be sung
有那麼多甜美的曲兒等我歌唱
So many wild pleasures lay in store for me
有那麼多肆意的快樂等我享受
And so much pain my eyes refused to see
還有那麼多痛苦 個人雙眼卻視而不見
I ran so fast that time and youth at last ran out
我飛快地奔走 最終時光與青春消逝殆盡
I never stopped to think what life was all about
我從未停下腳步去思考生命的意義
And every conversation that I can now recall
現在回想起的全部對話
Concerned itself with me and nothing else at all
除了和我相關的 什麼都記不得了
The game of love I played with arrogance and pride
我用自負和傲慢玩着愛情的遊戲
And every flame I lit too quickly, quickly died
全部我點燃的火焰都熄滅得太快
The friends I made all somehow seemed to slip away
全部我交的朋友彷佛都不知不覺地離開了
And only now I'm left alone to end the play, yeah
只剩我一我的在臺上來結束這場鬧劇
Oh, yesterday when I was young
噢 昨日當我年少輕狂
So many, many songs were waiting to be sung
有那麼那麼多甜美的曲兒等我歌唱
So many wild pleasures lay in store for me
有那麼多肆意的快樂等我享受
And so much pain my eyes refused to see
還有那麼多痛苦 個人雙眼卻視而不見
There are so many songs in me that won't be sung
我有太多歌曲永遠不會被唱起
I feel the bitter taste of tears upon my tongue
我嚐到了舌尖淚水的苦澀滋味
The time has come for me to pay for yesterday
終於到了付出代價的時間 爲了昨日
When I was young
當我年少輕狂
View Code

read():讀取文件所有python3.x

打開文件並所有讀出(read()方法)緩存

f = open("demo", 'r', encoding="utf-8")
print(f.read())

write():寫入文件(寫入時指定編碼,wb形式沒法指定)app

f = open("demo", 'w', encoding="utf-8")
f.write('看看效果了\n')
f.write('換行了,不加反斜槓n不換行')

readline():讀取文件一行

f = open("demo", 'w', encoding="utf-8")
print(f.readline().strip())
print(f.readline().strip())
print(f.readline().strip())
print(f.readline().strip())

readlines():將文件全部按行劃分紅列表元素並裝入列表

f = open('demo', 'r', encoding='utf-8')
print(f.readlines())

# ['Somehow, it seems the love I knew was always the most destructive kind\n', '不知爲什麼,我經歷的愛情老是最具毀滅性的的那種\n',............'終於到了付出代價的時間 爲了昨日\n', 'When I was young\n', '當我年少輕狂']

for line in f.readlines():  # 循環打印全部
    print(line.strip())

# 跳過第九行打印
for index, line in enumerate(f.readlines()):
    if index == 9:
        print("==========================")
        continue
    print(line.strip())

注:循環讀出文件建議以下

for line in f:  # 這樣機器內存裏值保存一行,最高效

  print(line)

tell():返回文件內光標所在位置

f = open('demo', 'r', encoding='utf-8')
f.readline()
f.readline()
print(f.tell())

# 140

seek():將文件內光標移到指定位置

read()和write()都是在光標後讀寫,r+模式的默認例外

f.readline()
f.readline()
f.seek(2)
print(f.tell())

# 2

flush():將文件實時刷新到硬盤上(python3.x)

文件運行時是與緩存交換信息,等緩存滿了,緩存一次性刷到硬盤,硬盤(存二進制,插入需後面全日後移,不現實)改東西 只能覆蓋,不能插入
truncate():將文件截斷指定大小,默認截斷0
f.encoding   #查看使用open打開文件的編碼
f.closed       #文件若是關閉則返回True

文件打開模式分析

‘r’模式:只讀模式

只能讀取文件,是默認模式,文件必須存在,不存在則拋出異常

read()和write()都是在光標後讀寫,r+模式的默認例外

‘w’模式:只寫模式

用了只寫模式至關於從新建立問價,不可讀;不存在則建立;存在則清空內容重寫

’a’模式:追加模式

可讀;不存在則建立;存在則只追加內容。不管光標在哪,是否使用seek,追加模式只能在文件的末尾進行寫(追加)操做(a,a+)

’r+’模式:讀寫模式

可讀可寫,在不手動用seek()移動光標時,write()默認會寫到文件的最後,其他模式都是在光標後操做,由於在文件內寫是覆蓋,並非插入,爲了保護文件

可是若本身手動seek()移動了光標,則可在seek()處寫(實際上是覆蓋)(對比a,a+)

可是覆蓋也有問題(可能會有編碼錯誤)

‘w+’模式:寫讀模式

可讀可寫,可是由於是寫讀模式,相似‘w’模式,至關於從新建立文件,因此只能先寫在讀

‘rb’模式:二進制讀模式

二進制的方式讀取,不須要加編碼方式

f = open ( 'dingxi' , 'rb' )

文件修改

f=open('dingxi','r',encoding='utf8')
new_f=open('dingxi2','w',encoding='utf8')
for line in f:
    if '多想和你同樣臭不要臉' in line:
        line = line.replace('多想和你同樣臭不要臉','就是這麼的臭不要臉')
    new_f.write(line)
f.close()
new_f.close()

# 執行結果:建立一個新的文件,而且替換原來的‘多想和你同樣臭不要臉’

with語句

爲了不打開文件後忘記關閉,能夠經過with管理上下文,當with代碼塊執行完畢時,內部會自動關閉並釋放文件資源。with語句的基本語法結構以下:

with expression [as variable]:
    with-block

  在Python 2.7 後,with又支持同時對多個文件的上下文進行管理,即:

with open('dingxi','r',encoding='utf8') as f,open('Lry','r',encoding='utf8') as f1:
    print(f.readline())
    print(f1.readline())

  是否是發現使用with語句相對try/finally來講簡潔了不少,並且也不須要每個用戶都去寫f.close()來關閉文件了,這是由於with語句在背後作了大量的工做。with語句的expression是上下文管理器,這個咱們下文會說。with語句中的[as variable]是可選的,若是指定了as variable說明符,則variable是上下文管理器expression調用__enter__()函數返回的對象。因此,f並不必定就是expression,而是expression.__enter__()的返回值,至於expression.__enter__()返回什麼就由這個函數來決定了。with-block是執行語句,with-block執行完畢時,with語句會自動進行資源清理,對應上面例子就是with語句會自動關閉文件。

  下面咱們來具體說下with語句在背後默默無聞地到底作了哪些事情。剛纔咱們說了expression是一個上下文管理器,其實現了__enter__和__exit__兩個函數。當咱們調用一個with語句時,執行過程以下:

1.首先生成一個上下文管理器expression,在上面例子中with語句首先以「test.txt」做爲參數生成一個上下文管理器open("test.txt")。

2.而後執行expression.__enter__()。若是指定了[as variable]說明符,將__enter__()的返回值賦給variable。上例中open("test.txt").__enter__()返回的是一個文件對象給f。

3.執行with-block語句塊。上例中執行讀取文件。

4.執行expression.__exit__(),在__exit__()函數中能夠進行資源清理工做。上面例子中就是執行文件的關閉操做。

  with語句不只能夠管理文件,還能夠管理鎖、鏈接等等,以下面的例子:

#管理鎖
import  threading
lock = threading.lock()
with lock:
    #執行一些操做
    pass

下文管理器


   在上文中咱們提到with語句中的上下文管理器。with語句能夠如此簡單但強大,主要依賴於上下文管理器。那麼什麼是上下文管理器?上下文管理器就是實現了上下文協議的類,而上下文協議就是一個類要實現__enter__()和__exit__()兩個方法。一個類只要實現了__enter__()和__exit__(),咱們就稱之爲上下文管理器下面咱們具體說下這兩個方法。

  __enter__():主要執行一些環境準備工做,同時返回一資源對象。若是上下文管理器open("test.txt")的__enter__()函數返回一個文件對象。

  __exit__():完整形式爲__exit__(type, value, traceback),這三個參數和調用sys.exec_info()函數返回值是同樣的,分別爲異常類型、異常信息和堆棧。若是執行體語句沒有引起異常,則這三個參數均被設爲None。不然,它們將包含上下文的異常信息。__exit_()方法返回True或False,分別指示被引起的異常有沒有被處理,若是返回False,引起的異常將會被傳遞出上下文。若是__exit__()函數內部引起了異常,則會覆蓋掉執行體的中引起的異常。處理異常時,不須要從新拋出異常,只須要返回False,with語句會檢測__exit__()返回False來處理異常。

  若是咱們要自定義一個上下文管理器,只須要定義一個類而且是實現__enter__()和__exit__()便可。下面經過一個簡單的例子是演示若是新建自定義的上下文管理器,咱們以數據庫的鏈接爲例。在使用數據庫時,有時要涉及到事務操做。數據庫的事務操做當調用commit()執行sql命令時,若是在這個過程當中執行失敗,則須要執行rollback()回滾數據庫,一般實現方式可能以下:

def test_write():
    con = MySQLdb.connection()
    cursor = con.cursor()
    sql = """      #具體的sql語句
    """
    try:
        cursor.execute(sql)
        cursor.execute(sql)
        cursor.execute(sql)
        con.commit()      #提交事務
    except Exception as ex:
        con.rollback()    #事務執行失敗,回滾數據庫

  若是想經過with語句來實現數據庫執行失敗的回滾操做,則咱們須要自定義一個數據庫鏈接的上下文管理器,假設爲DBConnection,則咱們將上面例子用with語句來實現的話,應該是這樣子的,以下:

def test_write():
    sql = """      #具體的sql語句
    """
    con = DBConnection()
    with con as cursor:   
        cursor.execute(sql)
        cursor.execute(sql)
        cursor.execute(sql)

  要實現上面with語句的功能,則咱們的DBConnection數據庫上下文管理器則須要提供一下功能:__enter__()要返回一個鏈接的cursor; 當沒有異常發生是,__exit__()函數commit全部的數據庫操做。若是有異常發生則_exit__()會回滾數據庫,調用rollback()。因此咱們能夠實現DBConnection以下:

def DBConnection(object):
    def __init__(self):
        pass

    def cursor(self):
        #返回一個遊標而且啓動一個事務
        pass

    def commit(self):
        #提交當前事務
        pass

    def rollback(self):
        #回滾當前事務
        pass

    def __enter__(self):
        #返回一個cursor
        cursor = self.cursor()
        return cursor

    def __exit__(self, type, value, tb):
        if tb is None:
            #沒有異常則提交事務
            self.commit() 
        else:
            #有異常則回滾數據庫
            self.rollback()

Python 文件夾及文件操做

咱們常常會與文件和目錄打交道,對於這些操做,python可使用 os 及 shutill 模塊,其中包含了不少操做文件和目錄的函數。

  os 能夠執行簡單的文件夾及文件操做,引入用  import os,可用  help(os)  或是  dir(os)  查看其用法。注意有些函數在os模塊中,有的是在os.path模塊中。

  shutil 模塊提供了大量的文件的高級操做,特別針對文件拷貝和刪除。主要功能爲目錄和文件操做以及壓縮操做。須引入 import shutil  ,具體 help。本文僅介紹移動、複製及刪除。

  可先在 D:\ 下建立文件夾 Python_os , 再在其下建立文件夾 os, 再在其下建立 test.txt;以後的示例會在該文件夾下操做

      

判斷路徑或文件

    os.path.isabs(...)      # 判斷是否絕對路徑

    os.path.exists(...)     # 判斷是否真實存在

    os.path.isdir(...)       # 判斷是不是個目錄

    os.path.isfile(...)       # 判斷是不是個文件

  注意:   把兩個路徑合成一個時,不要直接拼字符串,而要經過 os.path.join(part1,part2) 函數,這樣能夠正確處理不一樣操做系統的路徑分隔符。在Linux/Unix/Mac下,os.path.join()返回這樣的字符串:    part1/part2

  而Windows下會返回這樣的字符串:  part1\part2

複製代碼
 1 import os
 2 import shutil
 3 
 4 file_dir = "D:\\Python_os\\os"                          # 注意 \\ ;windows 下是這麼表示的;Linux 和 Mac 是 /
 5 file_name = "test.txt"
 6 file_abs = os.path.join(file_dir, file_name)            # os.path.join(...) 表示路徑連接
 7 
 8 
 9 '''判斷路徑或文件'''
10 print (1,os.path.isabs(file_dir))                       # 判斷是否絕對路徑
11 print (2,os.path.isabs(file_name))                        
12 print (3,os.path.isabs(file_abs))                        
13 print (4,os.path.exists(file_abs))                      # 判斷是否真實存在
14 print (5,os.path.exists(os.path.join(file_dir,"xxx")))                
15 print (6,os.path.isdir(file_dir))                       # 判斷是不是個目錄
16 print (7,os.path.isdir(file_abs))        
17 print (8,os.path.isfile(file_dir))                      # 判斷是不是個文件
18 print (9,os.path.isfile(file_abs))        
複製代碼

運行結果: 

 

路徑名、文件名分隔

    os.path.split(...)            # 分隔目錄和文件名/文件夾名         

    os.path.splitdrive(...)        # 分隔盤符(windows系統)     

    os.path.splitext(...)           # 分隔文件和擴展名

運行結果:  

這些合併、拆分路徑的函數並不要求目錄和文件要真實存在,它們只對字符串進行操做。

 

工做目錄及建立文件夾操做

    os.getcwd()       # 獲取當前工做目錄

    os.chdir(...)       # 改變工做目錄

    os.listdir(...)      # 列出目錄下的文件

    os.mkdir(...)      # 建立單個目錄        注意:建立多級用 os.makedirs()

    os.makedirs(...)    # 建立多級目錄

複製代碼
 1 import os
 2 
 3 file_dir = "D:\\Python_os\\os"    
 4 
 5 print (os.getcwd())                                # 獲取當前工做目錄
 6 os.chdir(file_dir)                                 # 改變工做目錄
 7 print (os.getcwd())    
 8 print (os.listdir(file_dir))                       # 列出當前工做目錄的全部文件 Python2 不支持 os.listdir()    Python3 會列出當前工做目錄下的全部文件      
 9 os.mkdir("test_mkdir")                             # 在當前工做目錄下建立文件夾 test_mkdir;注意不可存在相同文件夾,否則會報錯
10 os.makedirs("test_mkdir\\test1")
11 os.chdir(".\\test_mkdir")                          # . 表示本級目錄; .. 表示上級目錄
12 print (os.getcwd())    
13 for i in range(2,6):                               # 使用for循環等,可方便的建立多個文件夾
14     dir_name = "test" + str(i)
15     os.mkdir(dir_name)    
複製代碼

在執行了上述實例代碼後,os 文件夾中新建了空的 test_mkdir 文件夾,而 test_dir 文件夾下也新建出了 test1 至 test5 的空文件夾

   

 建立文件夾可能會出錯,緣由具體有:(1) path 已存在時(不論是文件仍是文件夾)  (2) 驅動器不存在  (3) 磁盤已滿  (4) 磁盤是隻讀的或沒有寫權限

刪除文件夾/文件

    os.rmdir(...)            # 刪除空文件夾                     注意:必須爲空文件夾  如需刪除文件夾及其下全部文件,需用 shutil

    os.remove(...)                   # 刪除單一文件

    shutil.rmtree(...)               # 刪除文件夾及其下全部文件

在上方示例的文件夾基礎上,操做刪除 test1 文件夾 (空文件夾可用 os.rmdir() ),刪除 test_mkdir 及其下全部文件();示例代碼以下

複製代碼
 1 import os
 2 import shutil
 3 
 4 file_dir = "D:\\Python_os\\os"                    
 5 
 6 ''' 刪除文件/文件夾 '''
 7 os.chdir(file_dir+"\\test_mkdir")                    
 8 print(os.getcwd())                                    # 確保當前工做目錄
 9 print(os.listdir(os.getcwd()))                        # 查看當前文件夾下全部文件    
10 os.rmdir("test1")                                     # 刪除 test1 文件夾(空文件夾)
11 print(os.listdir(os.getcwd()))    
12 os.chdir("..\\")
13 print(os.getcwd())                                    # 切換到上級目錄
14 print(os.listdir(os.getcwd()))
15 shutil.rmtree("test_mkdir")                           # 刪除 test_mkdir 及其下全部文件
複製代碼

 可見運行結果以下;產生異常的可能緣由:  (1) 路徑不存在 (2) 路徑子目錄中有文件或下級子目錄(os.rmdir) (3) 沒有操做權限或只讀

只是刪除單一文件,則用   os.remove("test.txt")   便可;產生異常的可能緣由:  (1) 文件不存在   (2) 對該文件沒有操做權限或只讀。

 

重命名文件夾/文件

可對某一文件或文件夾重命名   os.rename(oldfileName, newFilename)  

在os文件夾中新建文件夾 test,文件 test.txt  

複製代碼
1 ''' 重命名文件夾/文件 '''
2 os.chdir(file_dir)
3 print(os.listdir(os.getcwd()))
4 os.rename("test","test1")    
5 os.rename("test.txt","test1.txt")                # 重命名,注意須要帶擴展名
6 print(os.listdir(os.getcwd()))
複製代碼

可見運行結果以下;產生異常的可能緣由:  (1) oldfilename 舊文件名不存在(文件須帶擴展名)   (2)newFilename 新文件已經存在

注意:新文件的擴展名不能遺漏,理論上須要保持類型一致;但這也不失爲改文件類型的一種方式(至關於直接改文件的擴展名) 

複製、移動文件夾/文件

須使用 shutil 模塊,引入 import shutil 

    shutil.copyfile("old","new")       # 複製文件,都只能是文件

    shutil.copytree("old","new")     # 複製文件夾,都只能是目錄,且new必須不存在

    shutil.copy("old","new")           # 複製文件/文件夾,複製 old 爲 new(new是文件,若不存在,即新建),複製 old 爲至 new 文件夾(文件夾已存在)

    shutil.move("old","new")          # 移動文件/文件夾至 new 文件夾中

咱們如今 D:\ 下建立新文件夾 Python_shutil ,而後工做目錄切到該目錄,直接使用 Python 來操做吧,參考代碼以下:

複製代碼
1 import os
2 import shutil
3 
4 os.chdir("D:\\")
5 os.mkdir("Python_shutil")
6 file_dir = "D:\\Python_shutil"
7 os.chdir(file_dir)
複製代碼

爲演示覆制、移動操做,咱們在該文件夾下手動操做 新建文件夾 test_org、 test_copy 及 test_move; 新建文件 test.txt  test1.txt , 二者內容不一樣

   

Python 複製、移動的操做示例代碼以下:

複製代碼
 1 import os
 2 import shutil
 3 
 4 file_dir = "D:\\Python_shutil"
 5 os.chdir(file_dir)
 6 shutil.copyfile("test_org.txt","test_copy.txt")        # copy test_org.txt 爲 test_copy.txt 若存在,則覆蓋
 7 shutil.copyfile("test_org.txt","test1.txt")            # 存在,覆蓋
 8 shutil.copytree("test_org","test_copytree")            # copy test_org 爲 test_copytree(不存在的新目錄)
 9 shutil.copy("test_org.txt","test_copy1.txt")           # 同 copyfile
10 shutil.copy("test_org.txt","test_copy")                # 將文件 copy 至 目標文件夾中(須存在)
11 shutil.copy("test_org.txt","test_xxx")                 # 將文件 copy 至 目標文件(該文件可不存在,注意類型!)
12 print os.listdir(os.getcwd())
13 shutil.move("test_org.txt","test_move")                # 將文件 move 至 目標文件夾中
14 shutil.move("test_org","test_move")                    # 將文件夾 move 至 目標文件夾中
15 print os.listdir(os.getcwd())
複製代碼

 

   

文件操做實例

 複製粘貼博主的java教程中的doc文件

# Tools:Pycharm 2017.3.2
# author ="wlx"
__date__ = '2018/8/13 9:43'
import os
import shutil
path_root = 'G:\java教程\day'
path_append_list = os.listdir(path_root)  # 子目錄集
path_joint_list = []  # 須要進入的子目錄集
for p in path_append_list:  # 拼接後的目錄集
    path_joint_list.append(path_root+"\\"+p)
file_joint_list = []  # 存須要拷貝文件的地址集
for p in path_joint_list:
    file_list =  os.listdir(p)
    for f in file_list:
        if 'source' in f:
            file_joint_list.append(p+"\\"+f)
print(file_joint_list)
file_get_list = []
for f in file_joint_list:
    filename_list = os.listdir(f)
    for filename in filename_list:
        if "doc" in filename:
            file_get_list.append(f+"\\"+filename)
j = "1"
for i in file_get_list:
    # print(os.path.isfile(i))
    shutil.copy(i, 'G:\java教程\\'+j+'.doc')
    j = int(j)
    j += 1
    j = str(j)

 刪除文件的最後一行

# Tools:Pycharm 2017.3.2
# author ="wlx"
__date__ = '2018/8/12 20:37'
from collections import deque
deq = deque(maxlen=5)
print(deq.__len__())
with open('02第二模塊之三體語錄', 'r+', encoding='utf-8') as f:
    with open('new', 'w', encoding='utf-8') as f1:
        while True:
            line = f.readline()
            if line:
                deq.append(line)
                if deq.__len__() == 5:
                    f1.write(deq[0])
            else:
                break
        for i in range(3):
            f1.write(deq[i+1])

 讀取文件最後一行

# Tools:Pycharm 2017.3.2
# author ="wlx"
__date__ = '2018/8/13 11:03'
'''
f_name爲所讀xx.txt文件
輸出爲:文件最後一行
'''

fname = 'test.txt'
with open(fname, 'r') as f:  # 打開文件
    first_line = f.readline()  # 讀第一行
    off = -50  # 設置偏移量
    while True:
        f.seek(off, 2)  # seek(off, 2)表示文件指針:從文件末尾(2)開始向前50個字符(-50)
        lines = f.readlines()  # 讀取文件指針範圍內全部行
        if len(lines) >= 2:  # 判斷是否最後至少有兩行,這樣保證了最後一行是完整的
            last_line = lines[-1]  # 取最後一行
            break
        # 若是off爲50時獲得的readlines只有一行內容,那麼不能保證最後一行是完整的
        # 因此off翻倍從新運行,直到readlines不止一行
        off *= 2

print('文件' + fname + '第一行爲:' + first_line)
print('文件' + fname + '最後一行爲:' + last_line)

 實現對文件結束符(EOF)的判斷

法一:用sys.stdin

import sys 
for line in sys.stdin: 
    a=int(line) 
    if a!=0: 
        print(a)

法二:用try…except

try:
    while True:
        s = input()
except EOFError:
    pass