• Python3 IO编程之StringIO和BytesIO


      StringIO

       很多时候,数据读写不一定是文件,也可以在内存中读写。

      要把str写入StringIO,我们需要先创建一个StringIO,然后像文件一样写入即可

    >>> from io import StringIO
    >>> f=StringIO()
    >>> f.write('hello')
    5
    >>> f.write(' ')
    1
    >>> f.write('world!')
    6
    >>> f
    <_io.StringIO object at 0x7f6bbc76e318>
    >>> f.getvalue()
    'hello world!'
    

       getvalue()方法用于获得写入后的str

      要读取StringIO,可以用一个str初始化StringIO,然后像读文件一样读取

    >>> f=StringIO('Hello!
    Hi!
    Goodbye!')
    >>> while True:
    ...   s=f.readline()
    ...   if s=='':
    ...     break
    ...   print(s.strip())
    ... 
    Hello!
    Hi!
    Goodbye!
    

     

      BytesIO

      StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。

      BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:

    >>> from io import BytesIO
    >>> f=BytesIO()
    >>> f.write('中文'.encode('utf-8'))
    6
    >>> f.getvalue()
    b'xe4xb8xadxe6x96x87'
    

       请注意,写入的不是str,而是经过UTF-8编码的bytes。

      和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:

    >>> from io import BytesIO
    >>> f=BytesIO(b'xe4xb8xadxe6x96x87')
    >>> f.read()
    b'xe4xb8xadxe6x96x87'
    

       

      StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。

      

      用一个列子加深对StringIO和BytesIO的理解

    # StringIO和BytesIO
    
    # stringIO 比如说,这时候,你需要对获取到的数据进行操作,但是你并不想把数据写到本地硬盘上,这时候你就可以用stringIO
    from io import StringIO
    from io import BytesIO
    def outputstring():
        return 'string 
    from 
    outputstring 
    function'
    
    s = outputstring()
    #s为字符串'string 
    from 
    outputstring 
    function'
    
    #将函数返回的数据在内存中读
    sio=StringIO(s)
    #可以用StringIO本身的方法
    sio.getvalue()
    #输出
    #'string 
    from 
    outputstring 
    function'
    #也可以用file-like object的方法
    s=sio.readlines()
    #readlines返回的是一个列表
    #['string 
    ', 'from 
    ', 'outputstring 
    ', 'function']
    for i in s:
      print(i.strip())
    #去除尾部的回车符号输出
    #string
    #from
    #outputstring
    #function
    
    #将函数返回的数据在内存中写
    s=outputstring()
    sio=StringIO()
    sio.write(s)
    #如果是在终端会显示指针位置值36
    #可以用StringIO本身的方法查看
    print(sio.getvalue())
    
    #如果你用file-like object的方法查看的时候,你会发现数据为空
    #因为指针位置在尾部36
    for i in sio.readlines():
      print(i.strip())
    
    #这时候我们需要修改下文件的指针位置
    #就可以打印内容了
    sio.seek(0,0)
    #打印指针位置
    print(sio.tell())
    #结果为0
    # 这就涉及到了两个方法seek 和 tell
    # tell 方法获取当前文件读取指针的位置
    # seek 方法,用于移动文件读写指针到指定位置,有两个参数,第一个offset: 偏移量,需要向前或向后的字节数,正为向后,负为向前;第二个whence: 可选值,默认为0,表示文件开头,1表示相对于当前的位置,2表示文件末尾
    # 用seek方法时,需注意,如果你打开的文件没有用'b'的方式打开,则offset无法使用负值哦
    
    #在使用file-like object方法可以打印了
    for i in sio.readlines():
      print(i.strip())
    
    # stringIO 只能操作str,如果要操作二进制数据,就需要用到BytesIO
    # 上面的sio无法用seek从当前位置向前移动,这时候,我们用'b'的方式写入数据,就可以向前移动了
    bio=BytesIO()
    bio.write(s.encode('utf-8'))
    #使用getvalue()方法quzhi
    print(bio.getvalue())
    #b'string 
    from 
    outputstring 
    function'
    #修改指针
    #1代表从当前位置,-36代表往前移动36
    bio.seek(-36,1)
    bio.tell()
    #0
    for i in bio.readlines():
      print(i.strip())
    

      注意:当使用StringIO去初始化的时候,其指针是指向0的位置,而如果是用write的方法的时候,其指针会移动到最后

      举例如下

    >>> sio=StringIO('abc')
    >>> sio.getvalue()
    'abc'
    >>> sio.tell()
    0
    #初始化指针指向0 值为'abc'
    >>> sio=StringIO('def')
    >>> sio.tell()
    0
    >>> sio.getvalue()
    'def'
    #再次初始化会覆盖原值
    

       对比write方法

    >>> a=StringIO()
    #写指针加3
    >>> a.write('123')
    3
    #再次写追加指针再加3
    >>> a.write('456')
    3
    #值为追加非覆盖
    >>> a.getvalue()
    '123456'
    #最后指针为6
    >>> a.tell()
    6
    
  • 相关阅读:
    SD卡测试
    测试人员可能会遇到的问题
    HDU 1024 Max Sum Plus Plus
    HDU 1176 免费馅饼
    HDU 1257 最少拦截系统
    HDU 1087 Super Jumping! Jumping! Jumping!
    poj 1328 Radar Installation
    poj 1753 Flip Game
    HDU 1003 Max Sum
    HDU 5592 ZYB's Premutation(BestCoder Round #65 C)
  • 原文地址:https://www.cnblogs.com/minseo/p/11164921.html
Copyright © 2020-2023  润新知