input/output:输入、输出

Stream(流):Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。(流:相当于管道)

由于CPU和内存的速度远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。例如要把100M的数据写入磁盘,CPU输出100M的数据只需要0.01秒,磁盘要接收这100M数据可能需要10秒,所以存在两种模式:

  1. 同步IO:CPU等着,程序暂停执行后续代码,等100M的数据在10秒后写入磁盘,再接着往下执行
  2. 异步IO:CPU不等待,继续执行后续代码,后续再回来接收。(较复杂)

一、文件读写

  • 文件处理流程
  1. open()函数打开文件,得到文件句柄并赋值(不在同一路径下的需加 .py)
  2. 通过句柄对文件进行操作 (文件句柄相当于下文的 f )
  3. close()函数关闭文件
  • 文件打开模式

    • 读操作:解码默认GBK; open() 函数还可接收 errors 参数,可用  errors=ignore  忽略编码错误。

       r:只读,w:只写 ,a:追加
      f = open('文件名','权限',encoding='utf-8') #传入需要打开的文件名并进行解码
      data = f.read() #查看文件
      print(date)
      f.close() #关闭文件
       f = open('测试文件','r',encoding='utf-8')
      # date = f.read()
      # print(date) #文件只打印一次,后面再打印不显示内容
      # print(f.readable()) #判断权限
      # print(f.readline()) #打印一行,没内容即不打印
      print(f.readlines()) #将文件内容每段以字符串的方式显示出来,并存在一个列表中
      f.close() 输出:
      ['11111111111\n', '22222222222\n', '']
    • 写操作:直接新建空文档覆盖原来的文档

       f = open('测试文件','w',encoding='utf-8')
      f.write('1111\n')
      f.writelines(['','']) #以列表的方式写入,内容只能是字符串
      f.writable()
      f.close()
    • 追加操作:将内容写到文件最后,不覆盖文件内容
    • r+:可读可写;w+a+x+。
       f = open('测试文件','r+',encoding='utf-8')
      f.write('内容') #将内容覆盖到测试文件的开头,根据占用的字节进行替换
    • with...as...:可不用  close() 关闭文件
       #可使用with..as..:来打开或修改文件,不需要用close关闭。
      with open('测试文件','r',encoding='utf-8') as arc_f,/ #字符太长使用‘/‘进行换行处理
      open('新文件','w',encoding='utf-8') as dst_f:
    • 修改文件上的内容
       #查看文件内容并赋值到date上
      src_f = open('测试文件','r',encoding='utf-8')
      date = src_f.readline()
      src_f.close()
      #修改date索引位置的内容
      dst_f = open('测试文件','w',encoding='utf-8')
      dst_f.writelines(date[0])
      dst_f.close()
    • rb、wb、ab:可用于读取二进制文件,比如图片、视频等,不能指定编码(Windows下的换行为\r\n,Linux为\n。 编码后再加 " newline=‘ ' ”读取文件真正换行符:\r\n)
    1. 转成二进制:字符串 -----》encode(编码)-----》》bytes
    2. 查看二进制:bytes -----》decode(解码)-----》》字符串
       #使用 rb 进行查看,返回二进制数
      f = open('test1.py','rb')
      date = f.read()
      print(date)
      f.close() 输出:
      b'11111\r\n\xe4\xbd\xa0\xe5\xa5\xbd\r\n' 
       #使用 wb 新建文件或写入内容,需进行编码
      f = open('test1.py','wb')
      date = f.write('1234\n你好'.encode('utf-8'))
      4# date = f.write(bytes('1234\n你好',encoding='utf-8'))
      f.close()
    • flush():刷新文件
    • seek():里面加数字,表示文件光标移动多少个字节(一个汉字占用三个字节,排除第一个汉字时为:文件句柄.seek(3),默认为: 文件句柄.seek(3,0) )

      • 文件句柄.seek(3,1)表示相对位置,即从上一个移到的位置接着往下移动;文件句柄.seek(-3,2)表示光标从后往前的位置。
    • read():文件句柄.read(1)表示读取文件一个位置的内容,汉字占用三个字节也用一个表示。与其它方法的表示不一样
    • truntruncate():加数字表示截取文件多少个字节的内容。需以写的方式打开,w与w+除外。

       #使用seek倒查文件最后一行
      f = open('test.txt', 'rb')
      for i in f: # 使用for i in f 系统不会把所有数据读到内存中,而是需要读取时再读
      offs = -10 # 定义一个偏移量,因为倒查,所以为负数
      while True:
      f.seek(offs, 2) #
      data = f.readlines() # 使用readlines(),会得到一个光标所在位置到结尾所有行的一个列表
      if len(data) > 1: # 当列表大于1时,说明已取到完整的最后一行
      print(data[-1].decode('utf-8'))
      break
      offs *= 2 # 如果得到的列表不大于1,说明最后一行得到了一部分,就把偏移量*2,再进行循环

二、StringIO和BytesIO

  • StringIO:在内存中读、写str,可先用一个str 初始化内容

     #读取StringIO内的文件
    from io import StringIO
    f = StringIO('hello\nhi\ngoodbye')
    while True:
    s = f.readline()
    if s == '':
    break
    print(s.strip()) 输出:
    hello
    hi
    goodbye
     #将字符串写入StringIO
    from io import StringIO
    f = StringIO()
    date = f.write('hello')
    f.write(' ')
    f.write('world!')
    print(date)
    print(f.getvalue()) #getvalue 获取写入后的字符串 输出:
    5
    hello world!
  • BytesIO:在内存中读、写二进制数据
     #将bytes写入BytesIO
    from io import BytesIO
    f = BytesIO()
    date = f.write('中文'.encode('utf-8')) #需将str经过utf-8编码为bytes
    print(date)
    print(f.getvalue()) 输出:
    6
    b'\xe4\xb8\xad\xe6\x96\x87'

三、操作文件和目录

  • 使用os模块可直接调用操作系统提供的接口函数

     import os
    print(os.name) 输出:
    nt

    如果是posix,说明系统是LinuxUnixMac OS X,如果是nt,就是Windows系统; uname() 函数可查看详细系统信息,Windows上不提供该函数;

  • 环境变量:保存在os.environ变量中,获取某个变量的值可用 os.environ,get('key’) 进行调用;
  • 文件操作:使用 os.path.join() 函数将两个路径合并,可处理不同操作系统的分割符( Windows:\ ;Linux:/ 
     import os
    d = os.path.abspath('.') #查看当前目录的绝对路径
    #os.path.join('/Users/michael', 'testdir') #在Linux下创建;
    os.path.join('C:\\Users\\F·iy\\Desktop','testdir') #创建新目录,先表示出新目录的完整路径;
    os.mkdir('C:\\Users\\F·iy\\Desktop\\testdir') #创建目录
    os.rmdir('C:\\Users\\F·iy\\Desktop\\testdir') #删除目录

    使用 os.path.split() 函数对路劲拆分为两部分,后部分为最后的文件目录或文件名; os.path.splitext() 函数可得到文件扩展名; os.rename() 对文件重命名

     os.path.split('C:\\Users\\F·iy\\Desktop\\testdir')
    os.path.splitext('test.py') #得到('test', '.py')
    os.rename('test.txt','test.py') #将.txt改为.py文件
    os.remove('test.py') #删掉文件
     #列出当前目录下的所有文件
    a = [x for x in os.listdir('.') if os.path.isdir(x)]
    #列出所有的.py文件
    b = [x for x in os.listdir('.') if os.path.splitext(x)[1]=='.py']
    print(a,b) 输出:
    ['__pycache__'] ['func.py', 'test.py', '__init__.py']

四、序列化

  把变量从内存中变成可存储或传输的过程;(特定的序列化称为pickling)

  序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

  反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

 #使用pickle.dump()与pickle.load()

 import pickle
d = dict(name='jack',age=18)
#直接把对象序列化后写入一个file-like Object(one.txt)里;
f = open('one.txt','wb')
pickle.dump(d,f)
f.close()
#从一个file-like Object里直接反序列化出对象
f = open('one.txt','rb')
d = pickle.load(f)
print(d) 输出:
{'name': 'jack', 'age': 18}
 #使用pickle.dumps() 与pickle.loads()

 import pickle
d = dict(name='jack',age=18)
a = pickle.dumps(d) #把任意对象序列化成一个bytes
b = pickle.loads(a) #反序列化出对象
print(a)
print(b) 输出:
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00jackq\x02X\x03\x00\x00\x00ageq\x03K\x12u.'
{'name': 'jack', 'age': 18}
  • JSON:序列化的标准格式  json模块  更通用、更符合web标准。

     #使用json.dumps()与json.loads()
    
     import json
    d = dict(name='Bob', age=20, score=88)
    a = json.dumps(d) #直接返回一个str
    b = json.loads(a) #反序列化
    print(a)
    print(b) 输出:
    {"name": "Bob", "age": 20, "score": 88}
    {'name': 'Bob', 'age': 20, 'score': 88}
     import json
    d = dict(name='Bob', age=20)
    #创建文件
    f = open('text.txt','w')
    json.dump(d,f)
    #反序列化
    f = open('text.txt','r')
    b = json.load(f)
    print(b) 输出:
    {'name': 'Bob', 'age': 20
  • 序列化 class 类,先将其转化为  dict  形式,使用 default 转换为可序列对象;反序列化时用 loads() 转换出一个dict对象后,使用 object_hook负责把 dict 转换为 Student 实例 
     import json
    
     class Student(object):
    def __init__(self, name, age, score):
    self.name = name
    self.age = age
    self.score = score def get(self):
    return '%s age is %s ,score:%s'% (self.name,self.age,self.score)
    #为class写一个转换函数
    def student_dict(std):
    return {
    'name': std.name,
    'age': std.age,
    'score': std.score
    } s = Student('jack', 18, 90)
    a = json.dumps(s, default=student_dict) #可选参数default可把任意一个对象变成一个可序列为JSON的对象
    #将class的实例变为dict,通常class的实例都有一个__dict__属性
    # print(json.dumps(s, default=lambda obj: obj.__dict__))
    print(a) #反序列化为class类的对象实例,先转换为dict后再转为实例
    def dict_student(d):
    return Student(d['name'], d['age'], d['score'])
    b = json.loads(a,object_hook=dict_student)
    print(b) #实例对象
    print(b.get()) 输出:
    {"name": "jack", "age": 18, "score": 90}
    <__main__.Student object at 0x000000B529F2C908>
    jack age is 18 ,score:90

五、IO编程的更多相关文章

  1. Java IO编程全解(五)——AIO编程

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7794151.html 前面讲到:Java IO编程全解(四)--NIO编程 NIO2.0引入了新的异步通道的 ...

  2. Java IO编程全解(六)——4种I/O的对比与选型

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面讲到:Java IO编程全解(五)--AIO编程 为了防止由于对一些技术概念和术语 ...

  3. Java IO编程全解(四)——NIO编程

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7793964.html 前面讲到:Java IO编程全解(三)——伪异步IO编程 NIO,即New I/O,这 ...

  4. 实验十五 GUI编程练习与应用程序部署

    实验十五  GUI编程练习与应用程序部署 实验时间 2018-12-6 一:理论部分 1.Java 程序的打包:编译完成后,程序员将.class 文件压缩打包为 .jar 文件后,GUI 界面序就可以 ...

  5. 20165324 Java实验五 网络编程与安全

    20165324 Java实验五 网络编程与安全 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年5月28日 实 ...

  6. python异步IO编程(二)

    python异步IO编程(二) 目录 开门见山 Async IO设计模式 事件循环 asyncio 中的其他顶层函数 开门见山 下面我们用两个简单的例子来让你对异步IO有所了解 import asyn ...

  7. 2018-2019-2-20175323 java实验五 网络编程与安全

    20175323 java实验五 网络编程与安全 任务一 ①编写MyBC.java实现中缀表达式转后缀表达式的功能 ②编写MyDC.java实现从上面功能中获取的表达式中实现后缀表达式求值的功能 基本 ...

  8. 面向对象的高级编程&IO编程

    1.给类对象绑定的函数,只对这个对象生效, 而对类绑定的对象, 所有的对象都可以调用. 栗子: def set_score(self, score): self.score = score s.set ...

  9. android 40 Io编程

    Io编程:内存卡和sd卡.字符串存入内存卡然后读出来. activity: package com.sxt.day06_06; import java.io.FileInputStream; impo ...

随机推荐

  1. 20165305 实验三 敏捷开发与XP实践

    实验3-1 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 参考 http://www.cnblog ...

  2. Linux服务器---流量监控webalizer

    webalize webzlizer是一个免费的web server分析工具,它能够分析apache.ftp等日志,将结果以html形式展示. 1.安装一些依赖软件 [root@localhost b ...

  3. PNG文件格式详解

    源文件地址:https://blog.mythsman.com/2015/12/08/1/ 最近在看隐写术的时候经常需要研究图片文件的二进制文档格式,那么这就很有必要了解我们的图片文件究竟是如何保存的 ...

  4. AtCoder Beginner Contest 083 (AB)

    A - Libra 题目链接:https://abc083.contest.atcoder.jp/tasks/abc083_a Time limit : 2sec / Memory limit : 2 ...

  5. [转载]Oracle ltrim() 函数用法

    前面有说到过LPAD和RPAD这两个函数用法的文章,今天发现与之相反意义的另外两个函数,那就是LTRIM() RTRIM(). 这次就挑LTRIM() 这一函数来讲讲: 具体的语法格式如下: LTRI ...

  6. Array和ArrayList不同

    Employee[] array = new Employee[10]; ArrayList<Employee> staff = new ArrayList<>(); 不同 A ...

  7. 怎样从外网访问内网MySQL数据库?

    本地安装了一个MySQL数据库,只能在局域网内访问到,怎样从外网也能访问到本地的MySQL数据库呢?本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动MySQL数据库 默认安装的MySQL ...

  8. python-selenium,关于页面滑动的操作

    //移动到元素element对象的“顶端”与当前窗口的“顶部”对齐 ((JavascriptExecutor) driver).executeScript("arguments[0].scr ...

  9. JS截取字符串中数字

    今天项目中需要在一个字符串中截取一个数字,然后数字参与运算.搜了一下,有好多好用的方式截取字符串. 1,使用parseInt() var str ="4500元"; var num ...

  10. oracle 12c AUTO_SAMPLE_SIZE动态采用工作机制

    The ESTIMATE_PERCENT parameter in DBMS_STATS.GATHER_*_STATS procedures controls the percentage of ro ...