引入
我们常说计算机有三层体系结构:最下层是硬件,硬件之上就是操作系统,最上层就是用户和应用程序。
用户和应用程序如果想操作硬件就必须通过操作系统,比如用户或者应用程序想要操作硬盘这个硬件就得操作操作系统,而操作系统提供了一种虚拟的概念,那就是文件,或者叫做操作系统提供的操作硬盘功能。用户或者应用程序想要把数据存到硬盘里去就需要对操作系统的文件发起系统调用,操作系统会把用户或者应用程序对文件的调用功能转成具体的硬盘操作,比如磁盘怎么转、磁头臂怎么摆,然后再把数据写到硬盘我们平时修改的文件都是借助文本编译器来实现修改文件的。
我们平时修改文件,都是借助文本编译工具来实现修改文件的,比如Visual Studio Code、Visual Studio、PyCharm、Word等等。当然,图片和视频也可以修改,图片对应的工具就是PS,图片数据就是16进制的,PS内所有的工具、画笔都是对颜色的修改,只不过是经过封装的而已。
文件的基本操作包括判断文件是否存在、打开、修改、关闭、删除和复制等。文件的打开与关闭是建立程序中的文件对象和文件的一种关联关系。文件的格式、类型不同他们打开的方式和读/写方式也不同。
1.文本文件
文本文件也称为ASCLL文件,存储的是字符串,且字符串中每个字符对应1个字节
2.二进制文件
二进制文件是指按二进制编码方式来存放内容的文件,二进制文件通常无法被直接被阅读和理解,所在我们需要专门的软件对二进制文件解码后才能读取、显示、修改和执行他。常见的图形/图像文件、音/视频文件、可执行文件、资源文件、各种数据文件、各类office文档等都属于二进制文件。系统在处理这些文件的时候,并不会区分类型,都将他们看做字符流,按字节进行处理。输入/输出字符流的开始和结束只由程序控制而不受物理符号的(如回车符)控制。因此这种文件也被称为"流式文件"
注意额外补充:
1.Linux和Unix使用的换行符是’\n’,而Windows使用的是’\r\n’,而MacOS早期使用的是’\r’,后来也转向使用’\n’
2.\r是回车符,\n是换行符
3.当在不同的操作系统中编辑或查看文本文件时,这些换行符可能会造成问题,因为每个操作系统都会使用不同的换行符。因此,在跨平台文件共享和协作中,必须对这些换行符进行适当的处理。
一般来说,当在Linux或Unix中查看Windows生成的文本文件时,你可能会看到额外的’\r’符号,当在Windows中查看Linux或Unix生成的文本文件时,你可能会看到文本被缩成了一行。在处理这些问题时,一种常见的方法是使用文本编辑器或工具来将文件中的换行符转换为特定的格式,如将’\r\n’转换为’\n’。这样可以使得文本文件在不同的操作系统中都能够正常地显示和编辑。
4.如果一个文件可以以文本模式或者二进制打开,那么会出现的问题就是“回车”会被当做一个字符,即“\n” ,文本模式会认为他是文件结束符,而二进制模式不会对"\n"进行处理
文件打开模式
模式 | 说明 |
---|---|
r | 只读模式 |
w | 写模式 |
a | 追加模式 |
b | 二进制模式(可与其他模式组合使用) |
+ | 读/写模式(可与其他模式组合使用) |
文件对象常用属性(仅列举了部分属性)
closed() #判断文件是否被关闭,若文件被关闭,则返回True
mode() #返回文件的打开模式
name() #返回文件名称
文件对象的 常用方法(不止以下几种)
open(filename, mode)按指定模式打开文件
read([size])
从文件中读取size个字节或字符的内容返回
若省略size则读取到文件末尾,即一次读取文件所有内容
readline()
从文本文件中读取一行内容
readlines()
把文本文件中每一行作为独立的字符串对象,并将这些对象放入列表返回
write(str)
将字符串str内容写入文件
writelines(s_list)
将字符串列表s_list写入到文本文件,不添加换行符
seek(offset[,whence])
把文件指针移动到新的位置,offset表示相对与whence的位置
offset:为正往结束方向移动,为负往开始方向移动
whence不同的值代表不同含义:
0:从文件头开始计算(默认值)
1:从当前位置开始计算
2:从文件尾开始计算
tell()
返回文件指针的当前位置
flush()
把缓冲区的内容写入文件,但不关闭文件
close()
把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源
1.创建文件 >> 读/写/查找/定位等操作 >> 关闭文件 (三部曲)
1、打开文件 open(“文件路径”, mode = “” [, encoding=“”])
2、操作文件 file.read() 、file.write() …
3、关闭文件 file.close()
2.with机制创建文件对象 >> 读/写文件 (两部曲)
with as 操作文件
使用这个写法就不用担心忘记关闭文件了。如果在进行文件读取操作的时候忘记关闭文件,你会发现文件会报错或者出现乱码,打不开的情况
with open(r'D:\WorkSpace\function_folder\file01.txt', mode='r',encoding='utf-8') as file:
msg = file.read()
print("with as 文件内容:", msg)
注意事项
报错:UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xb9 in position 26: incomplete multibyte sequence
解决办法:open(“文件路径”,mode=‘’,encoding=‘utf-8’) 加入编码格式即可
文件定位,指的是当前文件指针读取到的位置,光标位置
在读取文件的过程中,如果想知道当前的位置,可用tell()来获取
tell()
tell() 方法返回文件的当前位置,即文件指针当前位置。
语法: tell() 方法语法如下:
fileObject.tell()
参数: 无
返回值: 返回文件的当前位置。
实例
以下实例演示了 tell() 方法的使用:
文件 runoob.txt 的内容如下:
1:www.runoob.com
2:www.runoob.com
3:www.runoob.com
4:www.runoob.com
5:www.runoob.com
循环读取文件的内容:
# 打开文件
fo = open("runoob.txt", "rw+")
print ("文件名为: ", fo.name)
line = fo.readline()
print ("读取的数据为: %s" % (line))
# 获取当前文件位置
pos = fo.tell()
print ("当前位置: %d" % (pos))
# 关闭文件
fo.close()
'''
以上实例输出结果为:
文件名为: runoob.txt
读取的数据为: 1:www.runoob.com
当前位置: 17# 二进制文件操作
'''
如果在操作文件的过程中,需要定位到其他位置进行操作,可使用seek()
seek(offset,from),offset表示偏移量字节,负数为往前偏移,正数往后偏移
from表示位置,0表示文件开头,1表示当前位置,2表示文件末尾
seek() 方法用于移动文件读取指针到指定位置。
seek() 方法语法如下:fileObject.seek(offset[, whence])
参数 (offset whence) :
offset – 开始的偏移量,也就是代表需要移动偏移的字节数
whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。
返回值 : 如果操作成功,则返回新的文件位置,如果操作失败,则函数返回 -1。
实例
以下实例演示了 readline() 方法的使用:
文件 runoob.txt 的内容如下:
1:www.runoob.com
2:www.runoob.com
3:www.runoob.com
4:www.runoob.com
5:www.runoob.com
循环读取文件的内容:
#打开文件
fo = open("runoob.txt", "rw+")
print "文件名为: ", fo.name
line = fo.readline()
print "读取的数据为: %s" % (line)
#重新设置文件读取指针到开头
fo.seek(0, 0)
line = fo.readline()
print "读取的数据为: %s" % (line)
#关闭文件
fo.close()
以上实例输出结果为:
文件名为: runoob.txt
读取的数据为: 1:www.runoob.com
读取的数据为: 1:www.runoob.com
二进制文件操作与文本文件操作一样但需要注意的是,在使用open()方法打开或者创建一个二进制文件时需要指定打开模式为b
,同样的在进行二进制文件写操作时需要把写入的内容用b' '包围起来
转化为二进制数据
与文本文件一样,二进制文件对象的seek()方法用于文件指针定位,tell()方法用于查询文件指针位置
import os #导入os模块
fp = open(r'D:\python笔记', 'w+b') #以二进制写模式打开指定文件
fp.seek(0) #将文件指针定在最开始处
fp.write(b'Fear not for the future') #写入字节流
fp.seek(-7, os.SEEK_END) #定位到文件倒数第7行的位置
line = fp.read() #从当前位置到结束为止的所有字节流
print(line.decode()) #显示字节流
#运行结果: Shelly
#fp.tell() #tell()返回当前指针位置
运行结果: 68
csv : 纯文本形式储存表格数据(数字和文本,由任意数目的记录组成,excel表格方式打开)
1.将带有点坐标的 csv 转 geojson, 不带其他属性
将带有点坐标的 csv 转 geojson, 不带其他属性
import csv
csv_file = open('E:/test.csv', encoding='gbk')
csv_reader = csv.reader(csv_file)
geojson = '{"type":"FeatureCollection","features":['
for index, row in enumerate(csv_reader):
print(row[0])
geojson += '{"geometry":{"coordinates":[%f,%f],"type":"Point"},"properties":{},"type":"Feature"},' % (float(row[0]),float(row[1]))
geojson = geojson[:-1] + ']}'
links_file = open('test.geojson', 'w')
links_file.write(geojson)
2.将带有点坐标的 csv 转 geojson, 带其他属性
将带有点坐标的 csv 转 geojson, 带其他属性
import csv
import json
csv_file = open('test.csv', encoding='utf8')
csv_reader = csv.reader(csv_file)
geojson = '{"type":"FeatureCollection","features":['
lon_index = 0
lat_index = 1
for index, row in enumerate(csv_reader):
if index == 0:
header = row
continue
property_dict = {}
for indexJ, j in enumerate(row):
if indexJ == lon_index or indexJ == lat_index:
continue
property_dict[header[indexJ]] = j
geojson += '{"geometry":{"coordinates":[%f,%f],"type":"Point"},"properties":%s,"type":"Feature"},' \
% (float(row[lon_index]), float(row[lat_index]), json.dumps(property_dict, ensure_ascii=False))
geojson = geojson[:-1] + ']}'
links_file = open('test.geojson', 'w', encoding='utf8')
links_file.write(geojson)
geojson转geojson, 并加上一个随机数
geojson转geojson, 并加上一个随机数
import json
import random
file_object = open("D:/random_points.geojson", "r+", encoding='utf8')
file_data_str = file_object.read()
file_object.close()
origin_data = json.loads(file_data_str)
geojson = '{"type":"FeatureCollection","features":['
for i in origin_data["features"]:
properties = i["properties"]
properties["counts"] = random.randint(0, 20000)
geojson += '{"geometry":{"coordinates":%s,"type":"Point"},"properties":%s,"type":"Feature"},' % (
json.dumps(i["geometry"]["coordinates"]), json.dumps(i["properties"], ensure_ascii=False))
geojson = geojson[:-1] + ']}'
links_file = open('D:/random_points_value.geojson', 'w', encoding='utf8')
links_file.write(geojson)
将 csv 转为 json
import csv
import json
csv_file = open('F:/test.csv', encoding='utf8')
csv_reader = csv.reader(csv_file)
list_data = []
header = []
for index, row in enumerate(csv_reader):
if index == 0:
header = row
else:
one_json = {}
for index_j, j in enumerate(row):
one_json[header[index_j]] = row[index_j]
list_data.append(one_json)
json_data = {"data": list_data}
json_file = open('F:/test.json', 'w', encoding='utf8')
json_file.write(json.dumps(json_data, ensure_ascii=False))
1.读取含有点坐标的json文件, 并转为geojson
读取含有点坐标的json文件, 并转为geojson
import json
file_object = open("D:/收费员位置高德.json", "r+", encoding='utf8')
file_data_str = file_object.read()
file_object.close()
origin_data = json.loads(file_data_str)
geojson = '{"type":"FeatureCollection","features":['
for i in origin_data["data"]:
geojson += '{"geometry":{"coordinates":[%s,%s],"type":"Point"},"properties":{},"type":"Feature"},' % (
i["longitude"], i["latitude"])
geojson = geojson[:-1] + ']}'
links_file = open('D:/收费员位置高德.geojson', 'w', encoding='utf8')
links_file.write(geojson)
2.逐行读取含有点坐标的json文件, 并逐行写入geojson中
逐行读取含有点坐标的json文件, 并逐行写入geojson中
"""
import json
json_str = ""
for line in open("E:/income_province_evsmc.json"):
json_str += line
json_dict = json.loads(json_str)
file_writer = open("E:/points.geojson", "a+")
geojson = '{"type":"FeatureCollection","features":['
file_writer.write(geojson)
for index, i in enumerate(json_dict["result"]):
coords = "%f,%f" % (i["lon"], i["lat"])
file_writer.write('{"geometry": {"type": "Point", "coordinates": [%s]},"properties": {}}' % coords)
if index != len(json_dict["result"]) - 1:
、 file_writer.write(',')
file_writer.write(']}')
如果只需要对文件内容进行读/写操作,则可以使用上文介绍的文件对象(read(),write()…);如果需要的是文件路径,则可以使用os.path模块中的对象和目录;如果需要使用命令行读取文件内容,则可以使用fileinput模块;如果需要创建临时文件和目录。则可以使用tempfile模块。另外pathlib模块提供了大量用于表示和处理文件系统路径的类
os.path模块
shutil模块