# 一、读取相关操作: readline、readlines、read
#     1、readline:一次读取一行
#     2、readlines:将结果输出至列表
#     3、read:全部读取出来
# 二、写相关操作
#     1、write() : 只能写字符串 (f.write(1)) 或者 bytes类型(f.write('1'.encode('gbk'))),其他的会报错
#     2、writelines() : 可以写列表,但是里面也需要是字段串 或者 bytes类型
#     3、flush : 刷新,主要用于写操作,作用将内存中的数据写入到硬盘中去,大多数情况下不要执行,通常出现在测试场景    

# 一、读取相关操作: readline、readlines
# 1、readline:一次读取一行
# with open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='rt', encoding='utf8') as f:
#     # print(f.readline())  # 去读取一行内容
#     # chenhongwei: 123456
#     # print(f.readline())  # 去读取一行内容
#     # 1: 1
#     while True:
#         res = f.readline()
#         if not res:
#             break
#         print(res)
#
# print("readline:一次读取一行".center(80,'='))
#
# # 结果如下:
# # chenhongwei:123456
# #
# # 1:1
# #
# # 2:2
# #
# # 2:2
# #
# # 2:2
# #
# # 2:2
# #
# # ================================readline:一次读取一行=================================
#
# # 2、readlines:将结果输出至列表
#
# with open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='rt', encoding='utf8') as f:
#     while True:
#         res=f.readlines()
#         if len(res)==0:
#             break
#         print(res)
#     print("readlines:".center(20, '='))
# # ['chenhongwei:123456\n', '1:1\n', '2:2\n', '2:2\n', '2:2\n', '2:2\n']
# # =====readlines:=====
#
# # 注意:read 和 readline 都是讲内容读入内存,如果内容过大会导致内存溢出,
# # 如果还想将内容全部读入内存,则必须分多次读入,有两种实现方式:
# # for 循环读取 和while 循环读取  -- 之前讲过的 习惯用while限制read的大小这种方式  f.read(1024) 每次只读取1024个字节
#
#
# # 二、写相关操作
# #     1、write() : 只能写字符串 (f.write(1)) 或者 bytes类型(f.write('1'.encode('gbk'))),其他的会报错
# #     2、writelines() : 可以写列表,但是里面也需要是字段串 或者 bytes类型
# with open(r'E:\PycharmProjects\demo01\Egon202003\user',mode='at',encoding='utf-8') as f, \
#         open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='rt', encoding='utf-8') as f2:
#     l = ['111',222,'333','444']
#     # f.write(l)  # 报错,只能是字符串 TypeError: write() argument must be str, not list
#     # 此时要写入有两种方式:
#     # 1、遍历列表,将每个值转成字符串,在写入
#     for v in l:
#         f.write(str(v)+'\n')
#     res=f2.read() # 特别注意,这里只能读取到在你打开这个文件时的文件内容。不能读取到新写入的内容,并且你重新在这里面打开也不行,你关掉之前的文件,会得到你后面写入的内容
#     print("写入后:",res)
#     # 写入后: chenhongwei: 123456
#     # 1: 1
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     # 2: 2
#
#     with open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='rt', encoding='utf-8') as f3:
#         print("没有关掉文件,重新打开写入的文件后:",f3.read())
#     # 没有关掉文件,重新打开写入的文件后: chenhongwei: 123456
#     # 1: 1
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     f.close()  # 关掉文件
#     print("关掉文件后,再打开写入的文件后:",f2.read())
#     # 关掉文件后,再打开写入的文件后: 111
#     # 222
#     # 333
#     # 444
#
# with open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='rt', encoding='utf-8') as f4:
#     print("脱离刚刚写的代码,重新打开刚刚写完并关闭流的的文件后:",f4.read())  # 得到全部内容
#     # 脱离刚刚写的代码,重新打开刚刚写完并关闭流的的文件(with会自动关闭文件)后: chenhongwei: 123456
#     # 1: 1
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     # 111
#     # 111
#     # 222
#     # 333
#     # 444
#
#     # 2、直接用writelines(): 将内容写作一行
#     # t 模式 :
# with open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='at', encoding='utf-8') as f:
#     # f.writelines(['111',222,'333','444'])  # TypeError: write() argument must be str, not int
#     f.writelines(['5555','66666'])
#
# with open(r'E:\PycharmProjects\demo01\Egon202003\user', mode='rt', encoding='utf-8') as f4:
#     print("脱离刚刚写的代码,重新打开刚刚写完并关闭流的的文件后:",f4.read())  # 得到全部内容
#     # 脱离刚刚写的代码,重新打开刚刚写完并关闭流的的文件后: chenhongwei: 123456
#     # 1: 1
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     # 2: 2
#     # 111
#     # 222
#     # 333
#     # 444
#     # 555566666

    # b 模式 :
with open(r'E:\PycharmProjects\demo01\Egon202003\01python基础-23文件操作模式详解-文件操作其他的方法的文件',mode='wb+') as f:  # w a 若文件不存在就会创建空文件,r会报错
    l = [
        'qqqqqqqq11'.encode('gbk')
        ,b'wwwwwww11'   # 注意:这里如果是纯英文字符 可以直接加 b 在前面,和上面的写法一样(不管上面指定的什么编码都是一样)。
        ,'陈红伟'.encode('gbk')
    ]
    f.writelines(l)
    print(f.read().decode('gbk'))
    # 结果如下(空的):
    #

with open(r'E:\PycharmProjects\demo01\Egon202003\01python基础-23文件操作模式详解-文件操作其他的方法的文件',mode='rb') as f:
    print(f.read().decode('gbk'))
    # 结果如下:
    # qqqqqqqq11wwwwwww11陈红伟
    # 总结: 所以不能一边写一边读,会有问题.主要是没有控制文件指针(seek、tell),否则可以实现同时读和写

# 小总结:

# 补充1: 这两种写法都是同一个原理。
print('qqqqqqqq11'.encode('gbk'))
print(b'qqqqqqqq11')   # 注意:这里如果是纯英文字符 可以直接加 b 在前面,和上面的写法一样(不管上面指定的什么编码都是一样)。
# b'qqqqqqqq11'
# b'qqqqqqqq11'

# 补充2:这两种写法都是同一个原理。
print('陈红伟'.encode('utf-8'))
print(bytes('陈红伟',encoding='utf8'))
# b'\xe9\x99\x88\xe7\xba\xa2\xe4\xbc\x9f'
# b'\xe9\x99\x88\xe7\xba\xa2\xe4\xbc\x9f'



# 3、flush : 刷新,主要用于写操作,作用将内存中的数据写入到硬盘中去,大多数情况下不要执行,通常出现在测试场景
with open(r'E:\PycharmProjects\demo01\Egon202003\01python基础-23文件操作模式详解-文件操作其他的方法的文件',mode='wb+') as f:
    f.write('我是flush'.encode('utf8'))
    f.flush()
    print(f.read().decode('utf8'))  # 输出: (空白)
with open(r'E:\PycharmProjects\demo01\Egon202003\01python基础-23文件操作模式详解-文件操作其他的方法的文件',mode='rb') as f:
    print(f.read().decode('utf8'))  # 输出: 我是flush

# 4、判断文件是否与可读、可写、已关闭
with open(r'E:\PycharmProjects\demo01\Egon202003\01python基础-23文件操作模式详解-文件操作其他的方法的文件',mode='rb') as f:
    print(f.readable()) # True
    print(f.writable()) # False
    print(f.closed) # False
    print(f.name) # E:\PycharmProjects\demo01\Egon202003\01python基础-23文件操作模式详解-文件操作其他的方法的文件
    # print(f.encoding) # t 模式下可用; b模式下报错 AttributeError: '_io.BufferedReader' object has no attribute 'encoding'
print(f.closed) # True