ใน
บทที่แล้วได้พูดถึงการเปิดไฟล์เพื่ออ่านไปแล้ว
เมื่อสามารถเปิดอ่านไฟล์ได้แล้ว ต่อไปสิ่งที่จำเป็นไม่แพ้กันก็คือการเขียนไฟล์ขึ้นมาใหม่
การเปิดไฟล์สำหรับเขียน การเขียนไฟล์นั้นก็เช่นเดียวกับการอ่านไฟล์ คือจะต้องเปิดไฟล์ขึ้นมาเสียก่อน เพียงแต่ต้องกำหนดโหมดการใช้งานเป็น
w
หรือ
a
แทนที่จะเป็น
r
แบบตอนอ่าน
ที่อาจจะฟังดูแปลกหน่อยก็คือแม้ว่าไฟล์ที่จะเขียนนั้นยังไม่ได้มีตัวตนอยู่ก็ตาม แต่ก็ยังต้องใช้คำสั่ง
open
เพื่อเปิดอะไรที่ว่างเปล่านั้นขึ้น ซึ่งการเปิดในที่นี้นั้นเท่ากับเป็นการสร้างไฟล์ขึ้นมา
หาก
open
ไฟล์ในโหมด
w
จะพบว่าไฟล์นั้นถูกสร้างขึ้นมาทันทีหากมันไม่ได้มีตัวตนอยู่แต่แรก
f = open('xxxx.txt','w',encoding='utf-8')
f.close()
ลองไปดูจะพบว่ามีไฟล์ชื่อ
xxxx.txt โผล่มาในโฟลเดอร์เดียวกับไฟล์โปรแกรม และภายในว่างเปล่าไม่มีอะไร
โหมด
w
กับ
a
นั้นจะต่างกันตรงที่ว่าในกรณีที่ไฟล์เดิมมีตัวตนอยู่แล้วถ้าเป็นโหมด
w
ไฟล์จะถูกเขียนทับใหม่ทันที แต่ถ้าเป็น
a
จะเป็นการเขียนต่อจากไฟล์เดิม
การเขียนไฟล์ก็ต้องเลือกรูปแบบการเอนโค้ดเช่นกัน ในที่นี้ใช้เป็น utf-8 เช่นเคย
คำสั่งเขียนไฟล์ มี ๒ เมธอดที่ใช้ในการเขียนไฟล์ คือ
.write
กับ
.writelines
ข้อแตกต่างคือ
.write
จะใช้กับสายอักขระอันเดียว แต่
.writelines
จะใช้กับลิสต์ของสายอักขระ
กรณีที่ใช้กับสายอักขระเดียวยาวต่อเนื่อง จะใช้
.write
หรือ
.writelines
ก็ได้เหมือนกันทั้งคู่
s = '''เวลาที่เข้าหาผู้อื่น ให้มีหัวใจที่อบอุ่นดั่งฤดูใบไม้ผลิ
เวลาที่ทำงาน ให้มีหัวใจที่เร่าร้อนดั่งฤดูร้อน
เวลาที่คิดอะไร ให้มีหัวใจที่แจ่มใสดั่งฤดูใบไม้ร่วง
เวลาที่เผชิญหน้ากับตัวเอง ให้มีหัวใจที่เข้มงวดดั่งฤดูหนาว'''
f = open('samejima.txt','w',encoding='utf-8')
f.write(s)
#หรือ f.writelines(s)
f.close()
(
ที่มาของข้อความ)
แต่ถ้ามีสายอักขระหลายๆอันแยกกันอยู่จะใช้ได้แต่
.writelines
เช่น
s = ['เวลาที่เข้าหาผู้อื่น ให้มีหัวใจที่อบอุ่นดั่งฤดูใบไม้ผลิ', 'เวลาที่ทำงาน ให้มีหัวใจที่เร่าร้อนดั่งฤดูร้อน', 'เวลาที่คิดอะไร ให้มีหัวใจที่แจ่มใสดั่งฤดูใบไม้ร่วง', 'เวลาที่เผชิญหน้ากับตัวเอง ให้มีหัวใจที่เข้มงวดดั่งฤดูหนาว']
f = open('samejima.txt','w',encoding='utf-8')
f.writelines(s)
f.close()
เพียงแต่ว่าจะไม่มีการเว้นบรรทัดให้ระหว่างสายอักขระแต่ละท่อน ถ้าต้องการก็ต้องเพิ่มเอาเอง
ถ้าจะใช้
.write
ก็อาจใช้เป็น
f.write('\n'.join(s))
คือใช้เมธอด
.join
เพื่อรวมสายอักขระเข้าด้วยกันโดยมีการขึ้นบรรทัดใหม่เป็นตัวแบ่ง
หรืออาจจะเขียนต่อๆกันไปเลยก็ได้ การใช้คำสั่ง
.write
หลายครั้งจะเป็นการเขียนต่อไปเรื่อยๆ โดยจะไม่มีการขึ้นบรรทัดใหม่ให้ดังนั้นต้องเติม
\n
ไปด้วย
for a in s:
f.write(a+'\n')
สิ่งที่จะเขียนได้นั้นต้องเป็นสายอักขระเท่านั้น หากไม่ใช่สายอักขระก็ต้องแปลงก่อน
ตัวอย่าง โปรแกรมเขียนเลข 1 ถึง 10000 ลงไฟล์
f = open('10000.txt','w',encoding='utf-8')
for i in range(1,10001):
f.write('|%d|'%i)
if(i%100==0): f.write('\n') # ขึ้นบรรทัดใหม่ถ้านับถึง 100
f.close()
แค่พิมพ์โค้ดสั้นๆแค่นี้ก็มีเลขโผล่ขึ้นมาถึงหมื่นภายในพริบตา ขนาดไฟล์หลายสิบกิโลไบต์ ลองคิดดูว่าถ้าเปลี่ยนจากหมื่นเป็นพันล้านจะเป็นอย่างไร
เท่านี้ก็สามารถไปประยุกต์สร้างไวรัสอย่างง่ายๆได้แล้ว ลองเขียนโปรแกรมทำนองนี้แล้วส่งให้ไปรันในเครื่องคนอื่นก็จะเกิดไฟล์ขนาดใหญ่ขึ้นอย่างรวดเร็ว แค่คิดก็น่ากลัวแล้ว
ตัวอย่างทั้งหมดนี้ใช้โหมด
r
คือพอเปิดไฟล์มาก็จะถูกลบทิ้งแล้วเริ่มเขียนใหม่ทันที ถ้าอยากให้ไฟล์เขียนต่อก็แค่เปลี่ยน
r
เป็น
a
เท่านั้น ลองทำดูกันได้
การคัดลอกไฟล์ เมื่อสามารถเปิดอ่านและสามารถเขียนไฟล์ได้แล้ว ต่อไปสิ่งที่จะทำได้ตามมาอย่างไม่ยากก็คือการนำข้อมูลจากไฟล์หนึ่งคัดลอกไปลงในอีกไฟล์ ซึ่งก็คือการอ่านไฟล์หนึ่ง ดึงข้อมูลมา แล้วก็นำไปเขียนในอีกไฟล์ ลองดูตัวอย่าง
f1 = open('nishikaze.txt','r',encoding='utf-8') # เปิดไฟล์ต้นฉบับ
f2 = open('nishikaze2.txt','w',encoding='utf-8') # กำหนดไฟล์ใหม่ที่จะเขียน
a = f1.read() # นำข้อมูลจากไฟล์ต้นฉบับมาเก็บในตัวแปร
f2.write(a) # นำข้อมูลจากตัวแปรมาเขียนลงในไฟล์ใหม่
f1.close() # ปิดไฟล์ต้นฉบับ
f2.close() # ปิดไฟล์ที่เขียนเสร็จ
เท่านี้ก็จะได้ไฟล์ใหม่ที่เหมือนกับไฟล์ต้นฉบับทุกประการ
แต่ความจริงแล้วนอกจากนี้ยังมีอีกวิธีที่ง่ายกว่านั้น นั่นคือใช้ฟังก์ชัน
copyfile
ในมอดูล
shutil
import shutil
shutil.copyfile('nishikaze.txt', 'nishikaze2.txt')
นอกจากนี้ยังมีฟังก์ชัน
move
เอาไว้ย้ายไฟล์
import shutil
shutil.move('nishikaze2.txt', 'nishikaze3.txt')
เท่านี้ข้อมูลจากไฟล์เดิมก็ย้ายไปอยู่ในไฟล์ชื่อใหม่
แค่การคัดลอกมาทั้งหมดอาจดูง่ายไปไม่ค่อยมีอะไร เราลองมาทำอะไรที่ต้องออกแรงมากกว่านั้นสักหน่อย
ต่อไปเป็นการนำข้อความจากไฟล์ต้นฉบับมาแตกออกเป็นไฟล์ย่อยแบ่งทีละบรรทัด
f = open('nishikaze.txt','r',encoding='utf-8') # เปิดไฟล์ต้นฉบับ
i = 1
for r in f: # วนซ้ำเพื่อแยกวิเคราะห์ทีละบรรทัด
if(r=='\n'): continue # หากบรรทัดไหนว่างเปล่าก็ข้ามไปเลย ไม่ต้องสร้างไฟล์ บรรทัดที่ว่างคือบรรทัดที่มีแต่ \n คือคำสั่งขึ้นบรรทัดใหม่
fw = open('n%02d.txt'%i,'w',encoding='utf-8') # สร้างไฟล์ใหม่ ตั้งชื่อเป็น n ตามด้วยหมายเลข
fw.writelines(r) # เขียนข้อมูลที่อ่านได้ในบรรทัดนั้นลงไฟล์
fw.close() # ปิดไฟล์ที่เขียน
i += 1
f.close() # ปิดไฟล์ต้นฉบับ
การจัดเก็บข้อมูลเพื่อใช้งาน โดยทั่วไปแล้วข้อมูลมักจะถูกจัดเก็บเป็นแถวๆอย่างเป็นระเบียบเพื่อให้อ่านง่ายและสะดวกต่อการใช้งาน
เราอาจเก็บข้อมูลในลักษณะคล้ายตารางโดยแยกเป็นแถวและมีการเว้นวรรคระหว่างข้อมูลแต่ละตัว
ยกตัวอย่าง เช่นสร้างระบบบันทึกคะแนนสอบโดยให้นักเรียนแต่ละคนป้อนคะแนนสอบแต่ละวิชาแล้วข้อมูลก็ถูกบันทึกลงไปเรื่อยๆ
rahat = input('ป้อนรหัสผู้สอบ: ')
physics = input('คะแนนฟิสิกส์: ')
chemi = input('คะแนนเคมี: ')
chiwa = input('คะแนนชีวะ: ')
f = open('khanaen.txt','a',encoding='utf-8')
f.write('%s %s %s %s\n'%(rahat,physics,chemi,chiwa))
f.close()
แบบนี้พอรันโปรแกรมแต่ละครั้งก็จะมีข้อความขึ้นมาให้กรอกรหัส แตามด้วยคะแนนแต่ละวิชา เมื่อกรอกครบคะแนนก็จะถูกบันทึกลงไฟล์
สมมุติว่ามีนักศึกษามาบันทึกคะแนนแล้วทั้งหมด ๓ คน ไฟล์ก็จะออกมาในลักษณะนี้
590001 90 76 84
590003 99 90 88
590007 80 92 100
ข้อมูลแบบนี้นำมาใช้งานได้ง่าย หากต้องการดึงข้อมูลคะแนนทั้งหมดมาวิเคราะห์ก็เปิดไฟล์ขึ้นมาอ่านแล้ว
.read
แล้ว
.split
แยกเอาแต่ละส่วน
เช่นเอาข้อมูลที่ได้นี้มาหาค่าต่ำสุด สูงสุด และค่าเฉลี่ย
f = open('khanaen.txt','r',encoding='utf-8')
physics = []
chemi = []
chiwa = []
for s in f:
a = s.split()
physics += [int(a[1])]
chemi += [int(a[2])]
chiwa += [int(a[3])]
f.close()
print('คะแนนฟิสิกส์ ต่ำสุด=%d, สูงสุด=%d, เฉลี่ย=%.2f'%(min(physics),max(physics),sum(physics)/len(physics)))
print('คะแนนเคมี ต่ำสุด=%d, สูงสุด=%d, เฉลี่ย=%.2f'%(min(chemi),max(chemi),sum(chemi)/len(chemi)))
print('คะแนนชีววิทยา ต่ำสุด=%d, สูงสุด=%d, เฉลี่ย=%.2f'%(min(chiwa),max(chiwa),sum(chiwa)/len(chiwa)))
บางครั้งตัวกั้นข้อมูลก็อาจใช้แท็บ
\t
หรือในกรณีไฟล์ชนิด
.csv จะกั้นด้วยจุลภาค
,
จะใช้เป็นอะไรก็ได้ แต่เวลาเปิดอ่านข้อมูลก็ต้องรู้และระบุตัวแยกให้ถูกต้อง
สรุปเนื้อหา
- การเขียนไฟล์ก็คล้ายกับการอ่านไฟล์ ต้องเปิดไฟล์ขึ้นมาก่อน โดยต้องเลือกโหมดเป็น
w
หรือ a
w
กับ a
ต่างกันตรงที่ w
เป็นการเขียนทับ ส่วน a
เป็นการเขียนต่อ
- เมธอดที่ใช้เขียนคือ
write
และ writelines
write
ใช้กับสายอักขระ ส่วน writelines
ใช้กับลิสต์ของสายอักขระ
- การคัดลอกไฟล์ทำได้โดยเปิดไฟล์ขึ้นมาอ่านแล้วเขียนใส่อีกไฟล์ หรือใช้
shutil.copyfile
ก็ได้
- สามารถใช้การอ่านและเขียนไฟล์เพื่อจัดการกับข้อมูลอย่างเป็นระบบได้
อ้างอิง http://docs.python.jp/3/library/functions.html http://www.ops.dti.ne.jp/ironpython.beginner/textfile.html http://www.yukun.info/blog/2008/09/python-file-write-writelines.html