IO

参考:IO

#读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),
# 然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

try:
    #如果文件不存在,open()函数就会抛出一个IOError的错误
    #相对路径为当前py文件路径
    file=open('error.log','r')
    #read()方法可以一次读取文件的全部内容,
    # Python把内容读到内存,用一个str对象表示:
    text=file.read()
    print(type(text))
    print(text)
except IOError as e:
    print(e)
finally:
    #文件使用完毕后必须关闭
    if file:
        file.close()

#简化写法,自动执行close
#读取文本文件,并且是UTF-8编码的文本文件
with open('error.log','r') as file:
    # read()会一次性读取文件的全部内容
    # read(size)方法,每次最多读取size个字节的内容。
    # 调用readline()可以每次读取一行内容,
    # 调用readlines()一次读取所有内容并按行返回list
    #再同一个文件下以上read/write方法共享一个文件指针,当前read方法从前一个read方法的结束指针处开始读文件,
    #当text=='' 时表示文件已经读完。
    text = file.read()
    print(type(text))
    print(text)

    text = file.read(1024)
    print(type(text))
    print(text)

    text = file.readline()
    print(type(text))
    print(text)

    text = file.readlines()
    print(type(text))
    print(text)

#open()函数返回的这种有个read()方法的对象,不要求从特定类继承,只要写个read()方法就行。

#要读取二进制文件,比如图片、视频等等,用'rb'模式
#要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数
#在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。

with open('pink.png','rb') as file:
    pass

with open('error.log','r',encoding='GBK',errors='ignore') as file:
    pass

#调用open()函数时,传入标识符要可写文件权限
#读写都会移动文件指针。获得指针位置:file.tell() ,设置指针位置:file.seek(0)
# r 只读文件,打开文件后指针位于0,文件不存在会报错。rb 二进制读文件。
# r+ 可读可写,打开文件后指针位于0,读为从当前指针出开始到结尾,写为从当前指针出开始写逐个字符覆盖原先内容,读写文件时不会创建不存在的文件,会报错.
# rb+ 二进制格式读写文件,打开文件后指针位于0,文件不存在会报错。

# w只写文件,打开文件后指针位于0,在打开文件后原先内容即被清空,从头开始写。如果该文件不存在,创建新文件。 wb+ 二进制读写文件。
# w+ 读写文件,打开文件后指针位于0,在打开文件后原先内容即被清空,从头开始写,读为从当前指针出开始到结尾。写文件时如果该文件不存在,创建新文件。

# a 只追写文件,打开文件后指针位于end,写为从end开始写.不存在则创建 ,ab+ 追读写二进制。
# a+ 读 追写文件。打开文件后指针位于end,写为从end开始写,读为从当前指针出开始到结尾, 读写文件时不存在则创建。



with open('error.log','a+') as file:
    print('--------------------------------')
    print(file.tell())
    file.seek(0)
    print(file.readlines())
    file.write('fuck\n')
    print(file.tell())

#当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。
# 只有调用close()/flush()方法时,操作系统才保证把没有写入的数据全部写入磁盘。
# 忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险:

print('--------------------------')
#,数据读写不一定是文件,也可以在内存中读写。
from io import StringIO ,BytesIO
#写str
f = StringIO('Hello!\nHi!\nGoodbye!')

#逐字覆盖式写入
#f.write('fuck')
while True:
    s = f.readline()
    if s == '':
        break
    print(s)
#写bytes
f = BytesIO('中文'.encode('utf-8'))

#逐字覆盖式写入
#f.write(bytes(22))
print(f.getvalue())

import os
#操作系统类型
print(os.name)
#环境变量
env_info=os.environ
print(type(env_info))
print(env_info.get('ALLUSERSPROFILE','default value'))

# 查看当前目录的绝对路径:
current_path=os.path.abspath('.')
print(current_path)

#把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数,这样可以正确处理不同操作系统的路径分隔符。
full_path=os.path.join(current_path, 'testdir')
print(type(full_path),full_path)
# 然后创建一个目录,若存在则报错
os.mkdir(full_path)
# 删掉一个目录:
os.rmdir(full_path)
# 对文件重命名:
os.rename('G:\\Python\\PycharmProject\\learn_python\\FileIO\\fuck.py', 'fuckme.py')
# 删掉文件:
os.remove('G:\\Python\\PycharmProject\\learn_python\\FileIO\\fuckme.py')

#把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名,前一部分为剩余信息:
print(os.path.split(full_path))
#得到文件扩展名:('/path/to/file', '.txt')
print(os.path.splitext('/path/to/file.txt'))


import shutil

#复制文件,fsrc(可读),fdst(可写)都是文件对象,都需要打开后才能进行复制操作
f1=open('error.log','r')
f2=open('name_copy.log','w+')
shutil.copyfileobj(f1,f2)

#复制文件,fsrcpath,fdstpath,只修改文件内容,不修改书写权限与文件状态。
shutil.copyfile('error.log','name_copy_2.log')

#仅copy 读写权限,不更改文件内容,组和用户。frspath,dstpath
#shutil.copymode('error.log','name_copy.log')

# 复制所有的状态信息,包括权限,组,用户,时间等
#shutil.copystat(srcpath,dstpath)

#复制文件的内容以及权限,先copyfile后copymode
#shutil.copy(srcpath,dstpath)
# 复制文件的内容以及文件的所有状态信息。先copyfile后copystat
#shutil.copy2(srcpath, dstpath)

#递归的复制文件夹内容及读写权限,文件状态
shutil.copytree('src', 'dst')
#递归地删除文件夹
shutil.rmtree('dst')

# 递归的移动文件夹/文件,目标文件夹/文件不存在就创建
shutil.move('src', 'dst')

# 压缩打包
#base_name:压缩打包后的文件名或者路径名,忽略压缩扩展名。
#format:压缩或者打包格式    "zip", "tar", "bztar"or "gztar"
#root_dir : 将哪个目录或者文件打包(也就是源文件)
shutil.make_archive('dst', 'zip', root_dir='dst')
#列出路径下所有文件夹与文件,返回list[str]
type(os.listdir('.'))
#判断是否是文件夹
print(os.path.isdir('dst'))
#判断是否是文件
print(os.path.isfile('dst.zip'))

#列出当前路径下所有.py文件
print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py'])

#把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling
#序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
#反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

#pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件。或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object:

import pickle
d=dict(A='a',B='b')
f = open('dump.txt', 'wb')
pickle.dump(d, f)
f.close()

import pickle

# pickle.dumps(object)方法把任意对象序列化成一个bytes
# pickle.dump(object,f)直接把对象序列化后写入一个file-like Object:
with open('dump.txt', 'wb') as f:
    d = dict(A='a', B='b')
    print(d)
    pickle.dump(d, f)

# pickle.loads(bytes)方法反序列化出对象
# 用pickle.load(f)方法从一个file-like Object中直接反序列化出对象。
with open('dump.txt', 'rb') as f:
    d = pickle.load(f)
    print(d)

# 这个变量和原来的变量是完全不相干的对象,它们只是内容相同而已。
# 可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据。

# 更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。
#   JSON类型	Python类型
#   {}	        dict
#   []	        list
#   "string"	str
#   1234.56	    int或float
#   true/false	True/False
#   null   	    None

# obj-(obj2dict())->dict-->str
# str-->dict-(dict2obj())->obj
# 这个变量和原来的变量是完全不相干的对象,它们只是内容相同而已。
# json.dumps(object)方法可以把一个可序列化对象返回一个str,内容就是标准的JSON。类似的,dump(object,file)方法可以直接把JSON写入一个file-like Object。
# 要把JSON反序列化为Python对象,用loads(str)或者对应的load(file)方法,前者把JSON的字符串反序列化,后者从file-like Object中读取字符串并反序列化:

import json

print('---------------------')
d = dict(A='a', B='b')
print(d)
dict_str = json.dumps(d)
print(dict_str)

d = json.loads(dict_str)
print(d)


# 非dict类序列化
class Stu(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score

    def __str__(self):
        return 'name:%s,age:%s,score:%s' % (self.name, self.age, self.score)


# 对于非dict对象要定义一个函数将对象转化为一个dict,或者使用对象自带方法,object.__dict__方法(也有少数例外,比如定义了__slots__的class。)
def stu2dict(stu):
    return dict(name=stu.name, age=stu.age, score=stu.score)


stu = Stu('huang', 22, 88)
print(stu)

stu_str = json.dumps(stu, default=stu2dict)
print(stu_str)

stu_str = json.dumps(stu, default=lambda ob: ob.__dict__)
print(stu_str)


# 同样要定义一个方法完成dist->obj
def dict2stu(d):
    return Stu(d['name'], d['age'], d['score'])


stu = json.loads(stu_str, object_hook=dict2stu)
print(stu)

posted @ 2019-11-11 23:25  HQANG  阅读(180)  评论(0)    收藏  举报