Python中文件处理和序列化

1.文件和流    Python将每个文件都视为一个顺序的字节流。每个文件都结束于一个EOF(文件尾)标记,或结束于一个特定字节编号(由系统维护的一个管理数据结构记录)。程序“打开"文件时,Python会创建一个对象,并将一个”流“与那个对象关联。
    Python程序开始执行时,会创建3个文件流,包括sys.stdin,sys.stdout,sys.stderr。这些流在程序和特定文件/设备之间建立了沟通渠道。
2.创建顺序访问文件
               
               
                # Fig. 14.3: fig14_03.py
# Opening and writing to a file.
import sys
# open file
try:
   file = open( "clients.dat", "w" )  # open file in write mode
except IOError, message:              # file open failed
   print >> sys.stderr, "File could not be opened:", message
   sys.exit( 1 )
print "Enter the account, name and balance."
print "Enter end-of-file to end input."
while 1:
   try:
      accountLine = raw_input( "? " )   # get account entry
   except EOFError:
      break                             # user entered EOF
   else:
      print >> file, accountLine        # write entry to file
      
file.close()
模式               说明
"a"                所有输出都写到文件尾,如果指定的文件不存在,就创建一个
"r"            打开文件以便输入,如果文件不存在,就引发IOError异常
"r+"           打开文件以便输入和输出,如果文件不存在,就引发IOError异常
"w"            打开文件以便输出,如果文件存在,就删除其中所有数据,如果文件不存在,就创建一个
"w+"           打开文件以便输入和输出,如果文件存在,就删除其中所有数据,如果文件不存在,就创               建一个
"ab","rb","r+b" 打开文件以便进行二进制(也就是非文本形式)输入或输出。注意,只有在Windows和   "wb","w+b"      Macintosh平台才支持这些模式
               
    常用的文件对象的方法有close(),flush()等,可在Python中输入help(file)来获取更详细的信息。
3.从顺序访问文件读取数据
# Fig. 14.6: fig14_06.py
# Reading and printing a file.
import sys
# open file
try:
   file = open( "clients.dat", "r" )
except IOError:
   print >> sys.stderr, "File could not be opened"
   sys.exit( 1 )
   
records = file.readlines()   # retrieve list of lines in file
print "Account".ljust( 10 ),
print "Name".ljust( 10 ),
print "Balance".rjust( 10 )
for record in records:          # format each line
   fields = record.split()
   print fields[ 0 ].ljust( 10 ),
   print fields[ 1 ].ljust( 10 ),
   print fields[ 2 ].rjust( 10 )
file.close()
# Fig. 14.7: fig14_07.py
# Credit inquiry program.
import sys
# retrieve one user command
def getRequest():
   
   while 1:
      request = int( raw_input( "\n? " ) )
     
      if 1 = request = 4:
         break
   return request
# determine if balance should be displayed, based on type
def shouldDisplay( accountType, balance ):
   if accountType == 2 and balance  0:     # credit balance
      return 1
   elif accountType == 3 and balance > 0:   # debit balance
      return 1
   elif accountType == 1 and balance == 0:  # zero balance
      return 1
   else: return 0
# print formatted balance data
def outputLine( account, name, balance ):
   
   print account.ljust( 10 ),
   print name.ljust( 10 ),
   print balance.rjust( 10 )
# open file
try:
   file = open( "clients.dat", "r" )
except IOError:
   print >> sys.stderr, "File could not be opened"
   sys.exit( 1 )
print "Enter request"
print "1 - List accounts with zero balances"
print "2 - List accounts with credit balances"
print "3 - List accounts with debit balances"
print "4 - End of run"
# process user request(s)
while 1:
   request = getRequest()   # get user request
   if request == 1:         # zero balances
      print "\nAccounts with zero balances:"
   elif request == 2:       # credit balances
      print "\nAccounts with credit balances:"
   elif request == 3:       # debit balances
      print "\nAccounts with debit balances:"
   elif request == 4:       # exit loop
      break
   else:  # getRequest should never let program reach here
      print "\nInvalid request."
   currentRecord = file.readline()    # get first record
   # process each line
   while ( currentRecord != "" ):
      account, name, balance = currentRecord.split()
      balance = float( balance )
      
      if shouldDisplay( request, balance ):
         outputLine( account, name, str( balance ) )
      currentRecord = file.readline() # get next record
   file.seek( 0, 0 )                  # move to beginning of file
  
print "\nEnd of run."
file.close()                          # close file
4.将数据写入shelve文件# Fig. 14.9: fig14_09.py
# Writing to shelve file.
import sys
import shelve
# open shelve file
try:
   outCredit = shelve.open( "credit.dat" )
except IOError:
   print >> sys.stderr, "File could not be opened"
   sys.exit( 1 )
print "Enter account number (1 to 100, 0 to end input)"
# get account information
while 1:
   # get account information
   accountNumber = int( raw_input(
         "\nEnter account number\n? " ) )
      
   if 0  accountNumber = 100:
      
      print "Enter lastname, firstname, balance"
      currentData = raw_input( "? " )
      outCredit[ str( accountNumber ) ] = currentData.split()
   elif accountNumber == 0:
      break
outCredit.close()   # close shelve file
5.从shelve文件获取数据
# Fig. 14.9: fig14_09.py
# Reading a shelve file.
import sys
import shelve
# print formatted credit data
def outputLine( account, aList ):
   
   print account.ljust( 10 ),
   print aList[ 0 ].ljust( 10 ),
   print aList[ 1 ].ljust( 10 ),
   print aList[ 2 ].rjust( 10 )
# open shelve file
try:
   creditFile = shelve.open( "credit.dat" )
except IOError:
   print >> sys.stderr, "File could not be opened"
   sys.exit( 1 )
print "Account".ljust( 10 ),
print "Last Name".ljust( 10 ),
print "First Name".ljust( 10 ),
print "Balance".rjust( 10 )
# display each account
for accountNumber in creditFile.keys():
   outputLine( accountNumber, creditFile[ accountNumber ] )
creditFile.close()   # close shelve file
6.示例:一个事务处理程序
# Fig. 14.11: fig14_11.py
# Reads shelve file, updates data
# already written to file, creates data
# to be placed in file and deletes data
# already in file.
import sys
import shelve
# prompt for input menu choice
def enterChoice():
   
   print "\nEnter your choice"
   print "1 - store a formatted text file of accounts"
   print "    called \"print.txt\" for printing"
   print "2 - update an account"
   print "3 - add a new account"
   print "4 - delete an account"
   print "5 - end program"
   
   while 1:
      menuChoice = int( raw_input( "? " ) )
  
      if not 1 = menuChoice = 5:
         print >> sys.stderr, "Incorrect choice"
      else:
         break
      
   return menuChoice
   
# create formatted text file for printing
def textFile( readFromFile ):
   
   # open text file
   try:
      outputFile = open( "print.txt", "w" )
   except IOError:
      print >> sys.stderr, "File could not be opened."
      sys.exit( 1 )
   print >> outputFile, "Account".ljust( 10 ),
   print >> outputFile, "Last Name".ljust( 10 ),
   print >> outputFile, "First Name".ljust( 10 ),
   print >> outputFile, "Balance".rjust( 10 )
   # print shelve values to text file
   for key in readFromFile.keys():
      print >> outputFile, key.ljust( 10 ),
      print >> outputFile, readFromFile[ key ][ 0 ].ljust( 10 ),
      print >> outputFile, readFromFile[ key ][ 1 ].ljust( 10 ),
      print >> outputFile, readFromFile[ key ][ 2 ].rjust( 10 )
   outputFile.close()
# update account balance
def updateRecord( updateFile ):
   
   account = getAccount( "Enter account to update" )
   if updateFile.has_key( account ):
      outputLine( account, updateFile[ account ] ) # get record
      transaction = raw_input(
         "\nEnter charge (+) or payment (-): " )
      # create temporary record to alter data
      tempRecord = updateFile[ account ]
      tempBalance = float( tempRecord[ 2 ] )
      tempBalance += float( transaction )
      tempBalance = "%.2f" % tempBalance
      tempRecord[ 2 ] = tempBalance
      # update record in shelve
      del updateFile[ account ]   # remove old record first
      updateFile[ account ] = tempRecord
      outputLine( account, updateFile[ account ] )
   else:
      print >> sys.stderr, "Account #", account, \
         "does not exist."
# create and insert new record
def newRecord( insertInFile ):
   
   account = getAccount( "Enter new account number" )
   if not insertInFile.has_key( account ):
      print "Enter lastname, firstname, balance"
      currentData = raw_input( "? " )
      insertInFile[ account ] = currentData.split()
   else:
      print >> sys.stderr, "Account #", account, "exists."
# delete existing record
def deleteRecord( deleteFromFile ):
   
   account = getAccount( "Enter account to delete" )
   if deleteFromFile.has_key( account ):
      del deleteFromFile[ account ]
      print "Account #", account, "deleted."
   else:
      print >> sys.stderr, "Account #", account, \
         "does not exist."
      
# output line of client information
def outputLine( account, record ):
   
   print account.ljust( 10 ),
   print record[ 0 ].ljust( 10 ),
   print record[ 1 ].ljust( 10 ),
   print record[ 2 ].rjust( 10 )
# get account number from keyboard
def getAccount( prompt ):
   
   while 1:
      account = raw_input( prompt + " (1 - 100): " )
   
      if 1 = int( account ) = 100:
         break
   return account
# list of functions that correspond to user options
options = [ textFile, updateRecord, newRecord, deleteRecord ]
# open shelve file
try:
   creditFile = shelve.open( "credit.dat" )
except IOError:
   print >> sys.stderr, "File could not be opened."
   sys.exit( 1 )

# process user commands
while 1:
   choice = enterChoice()               # get user menu choice
   if choice == 5:
      break
   options[ choice - 1 ]( creditFile )  # invoke option function
   
creditFile.close()                      # close shelve file
7.对象序列化    ”序列化“(Serialization)是指将用户自定义类等复杂对象类型转换成字节集,以便存储或通过网络传输。序列化也称为”平坦化“(Flattening)或者”编组“(Marshalling).Python用pickle和cPickle模块来执行序列化。
# Fig. 14.11: fig14_11.py
# Opening and writing pickled object to a file.
import sys, cPickle
# open file
try:
   file = open( "users.dat", "w" )    # open file in write mode
except IOError, message:              # file open failed
   print >> sys.stderr, "File could not be opened:", message
   sys.exit( 1 )
print "Enter the user name, name and date of birth."
print "Enter end-of-file to end input."
inputList = []
while 1:
   try:
      accountLine = raw_input( "? " )         # get user entry
   except EOFError:
      break                                   # user-entered EOF
   else:
      inputList.append( accountLine.split() ) # append entry
cPickle.dump( inputList, file )  # write pickled object to file
file.close()
# Fig. 14.13: fig14_13.py
# Reading and printing pickled object in a file.
import sys, cPickle
# open file
try:
   file = open( "users.dat", "r" )
except IOError:
   print >> sys.stderr, "File could not be opened"
   sys.exit( 1 )
   
records = cPickle.load( file ) # retrieve list of lines in file
file.close()
print "Username".ljust( 15 ),
print "Name".ljust( 10 ),
print "Date of birth".rjust( 20 )
for record in records:          # format each line
   print record[ 0 ].ljust( 15 ),
   print record[ 1 ].ljust( 10 ),
   print record[ 2 ].rjust( 20 )