Skip to content

Latest commit

 

History

History
234 lines (174 loc) · 4.89 KB

428-562133-[专业选修]按需读写.sy.md

File metadata and controls

234 lines (174 loc) · 4.89 KB
show version enable_checker
step
1.0
true

序列化

回忆

  • 上次我们研究数据序列化
    • 字符串
    • 字节型整数
    • 双精度浮点数
  • 依次写入
    • 然后可以进行数据类型转化
    • 并且进行运算
  • 可以对于序列化
    • 定点写入
    • 定点读取
  • 这并不难
  • 我们可以按照需求对文件进行读写操作么?

尝试使用命令行参数

  • 从游乐场跳转到操练场

图片描述

  • 带参数运行

图片描述

  • 实验结果明确

尝试序列化写入

import sys
import struct

f = open(sys.argv[1],"wt")
f.write(sys.argv[2])
f.write("\n")
f.close()
f = open(sys.argv[1],"ab")
hours = int(sys.argv[3])
b_hours = struct.pack("b",hours)
f.write(b_hours)
salary = float(sys.argv[4])
d_salary = struct.pack("d",salary)
f.write(d_salary)
f.close()
  • 给参数
python3 write.py oeasyd oeasy 4 11.1

查看结果

  • oeasyd结果

图片描述

  • %!xxd

图片描述

读出来

import sys
import struct
f = open(sys.argv[1],"rb")
b_name = f.readline()
s_name = b_name.decode()
s_name = s_name.replace("\n","")
f.close()
f = open(sys.argv[1],"rb")
f.seek(-9,2)
hours = f.read(1)
b_hours = struct.unpack("b",hours)[0]
f.seek(-8,2)
salary = f.read(8)
d_salary = struct.unpack("d",salary)[0]
f.close()
print(s_name,b_hours,d_salary)
  • 读出来是没问题的
    • 问题现在读了两次
  • 有可能只读一次
    • 然后切片(slice)么?

实验

图片描述

  • 现在得到的是一个字节序列

处理

  • 首先是不知道名字有多长
    • 如果我知道总长度
    • 然后减去后面的 9 个字节的数字位置
    • 然后再减去一个分隔符
    • 就可以知道名字的长度了

图片描述

  • 其实现在需要做的
    • 就是找到各个变量的首末位置
  • 只不过原来用的是f.seek
    • 现在应该用序列索引的方式

切片

  • 既然知道了名字字符串的长度
    • 然后就可以把名字先切出来
  • 用到的是一个切片操作
    • [0:5] 从第 0 个字节到第 5 个字节之前

图片描述

  • 切完了名字继续切数字
    • 名字之后有个\n

继续读

  • 计算位置
    • 名字的长度是 5
    • 加上回车是 6
    • 第 6 个字节就是工作时长的字节整型数字
    • 所以使用[6:7]
    • 截取这个字节

图片描述

  • 然后准备读取工资

再读

  • 第6个字节工作时长
  • 第7个字节到第14个字节
  • 总共八个字节
  • 正好对应这个8字节浮点数

图片描述

  • 读取出 double 型的 salary 数值
  • 然后进行输出

图片描述

  • 完成!✿

文件

import sys
import struct
f = open(sys.argv[1],"rb")
b = f.read()
length = len(b)
s_name = b[0: length-9].decode()
s_name = s_name.replace("\n","")
f.seek(-9,2)
hours = f.read(1)
b_hours = struct.unpack("b",hours)[0]
f.seek(-8,2)
salary = f.read(8)
d_salary = struct.unpack("d",salary)[0]
f.close()
print(s_name,b_hours,d_salary)
  • 既然能够一把读出来
  • 可以一把写进去么?

字节流写入

图片描述

  • 字节流整合
  • 确实可以串起来
  • 这样一把写入字节流就更合理了
  • 但是有个小问题
  • 字符串和数字部分之前没有分隔符
  • 还是得有个\n

图片描述

  • 这样就成功一次写入了
  • 而且是序列化地写入
  • 再去读出来

读出

图片描述

  • 首先定点读出数据
    • 确认写的位置
  • 如果是修改呢?
    • 每次都需要全读需全写么?
    • 能否只修改工作时间?

定点

  • 具体写入

图片描述

  • 可以看到\n之后的字节值
    • 被从0x05修改为0x03
  • 试验成功
  • 你可以把他落实为文件么?

总结

  • 这次研究了配合命令行参数的读写
    • 通过参数传递数据
    • python文件接收参数
    • 具体写某个文件
    • 写入某些数据
    • 然后再读取出来
    • 甚至可以定点修改
  • 可以从多个文件中读取么?
    • 每个文件中一个数字
    • 然后把他们都加起来?🤔
  • 下次再说 👋