相关文章推荐
强悍的海龟  ·  python自动化div ...·  1 年前    · 
健壮的爆米花  ·  有效解决 Unity3D Hub ...·  1 年前    · 

io流 (io stream)
流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。

输入输出(IO)是指计算机同任何外部设备之间的数据传递。常见的输入输出设备有文件、键盘、打印机、屏幕等。数据可以按记录(或称数据块)的方式传递,也可以流的方式传递。所谓记录,是指有着内部结构的数据块。记录内部除了有需要处理的实际数据之外,还可能包含附加信息,这些附加信息通常是对本记录数据的描述。

StringIO简介
StringIO是以流的方式对内存输入输出字符串。
StringIO的行为与file对象非常像,大多数方法使用都相似。但它不是磁盘上文件,而是一个内存里的"文件",在内存中读写str,我们可以像操作磁盘文件那样来操作StringIO,主要用于在内存缓冲区中读写数据。

python3中导入模块:

from io import StringIO
f = StringIO([buf])

StringIO对象被创建时,可通过字符串传递给对象初始化到一个现有的字符串。如果没有给出字符串,StringIO则将开始为空。
初始化的数据保存在缓冲区,可选参数buf是一个str或unicode类型。初始化的数据将会与后续写入数据存放一起。

如:aaaaaaaaaabbb会被放在一个缓冲区中。

>>> f = StringIO('aaaaaaaaa')
>>> f.write('bbb')
>>> f.getvalue()
'bbbaaaaaa'
在初始化时写出了aaaaaaaaaa,由于不是写入而是初始化,所以读写位置在下标为0。然后写入bbb,是从下标0开始写的,所以前3个字母会被覆盖。正确的处理方法应该是不使用初始化或者初始化之后将读写位置移动到末尾。

StringIO类中的方法:

(1)、f.read([n])
参数n限定读取长度,int类型;缺省状态为从当前读写位置读取对象中存储的所有数据。读取结束后,读写位置被移动。返回类型和操作file一样,为字符串。

(2)、f.readline([length])
参数length限定读取的结束位置,int类型; 缺省状态为None,从当前读写位置读取至下一个以"\n"为结束符的当前行。读写位置被移动。返回类型为字符串。

(3)、f.readlines([sizehint])
参数sizehint为int类型;缺省状态为读取所有行并作为列表返回, 且从当前读写位置读取至下一个以"\n"为结束符的当前行。读写位置被移动。返回类型为列表。

(4)、f.getvalue()
此函数没有参数,无论读写位置在哪里,都能够返回对象output中的所有数据,不影响读写位置。返回类型为字符串。

(1)、f.write(s)
从读写位置将参数s写入给对象output。参数s为str或unicode类型。读写位置被移动。返回类型为写入长度。

(2)、f.writelines(list)
从读写位置将list写入给对象output。参数list为一个列表,列表的成员为str或unicode类型。读写位置被移动。返回None。

(1)、f.truncate([size])
有size参数,无论读写位置在哪里,都从起始位置开始,裁剪size字节的数据,保留到对象中。
无size参数,将当前读写位置之前的数据,裁剪下来

(2)、f.tell()
返回当前读写位置,读写位置默认是0。

(3)、f.seek(pos[,mode])
移动当前读写位置至pos处,
可选参数mode:

  • 为0时将读写位置移动至pos处,mode的默认值为0。
  • 为1时将读写位置从当前位置起向前或向后移动|pos|个长度,
  • 为2时将读写位置置于末尾处再向前或向后移动|pos|个长度;
  • 返回结果为移动后的位置。

    (4)、f.close()
    释放缓冲区,执行此函数后,数据将被释放,也不可再进行操作。

    (5)、f.isatty()
    此函数总是返回0。

    (6)、f.flush()
    刷新内部缓冲区。

    from io import StringIO
    f = StringIO()
    f.write('快乐的国庆节\n')
    f.write('明年再见')
    print(f'当前读写位置:{f.tell()}')
    print(f.getvalue())
    print('*' * 20)
    f.seek(0)
    print(f'当前读写位置:{f.tell()}')
    # 如果不移动读写位置,read读取到的就是末尾的空字符串
    content = f.read()
    print(content)
    
    当前读写位置:11
    快乐的国庆节
    ********************
    当前读写位置:0
    快乐的国庆节
    

    从链接中读取文件

    import io
    import csv
    import requests
    course_2022 = set()
    url = "https://media-zip1.baydn.com/storage_media_zip/sclorg/ca7dd3c92959339334baed3f7a7be610.d0b71aba48304d1621c9a93f07233786.csv"
    resp = requests.get(url)
    resp.encoding = "utf-8"
    # 将文件流转成StringIO
    csv_reader = csv.reader(io.StringIO(resp.text))
    for line in csv_reader:
        if line[-1] != "":
            course_2022.add(line[-1])