python 文件处理

目录

一、前期了解

1.操作文件了解

二、Python 操作文件

1.打开文件

1.1文件操作模式

2.读写文件

3.关闭文件

4.其他文件操作

5.对read方法做了优化

6.文件操作的所有内置方法

三、主动控制文件内指针移动

四、 文件的修改

1.文件修改方式一

2.文件修改方式二

3.小练习:实现动态查看最新一条日志的效果


一、前期了解

1.操作文件了解

  • 应用程序运行过程中产生的数据最先都是存放于内存中的,若想永久保存下来,必须要保存于硬盘中。
  • 应用程序若想操作硬件必须通过操作系统,而文件就是操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。

文件打开基本流程

1. 打开文件,由应用程序向操作系统发起系统调用open(...),操作系统打开该文件,对应一块硬盘空间,并返回一个文件对象赋值给一个变量f
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r

2. 调用文件对象下的读/写方法,会被操作系统转换为读/写硬盘的操作
data=f.read()

3. 向操作系统发起关闭文件的请求,回收系统资源
f.close()
  1. 调用 open() 方法打开文件:open() 方法会根据传入的参数创建一个文件对象(f),并返回该文件对象的引用。该方法的执行过程涉及到以下几个主要步骤:
    1. 检查文件名是否存在,如果不存在,则会抛出 FileNotFoundError 异常。
    2. 检查文件权限是否满足操作要求,如果不满足,则会抛出相应的异常。
    3. 创建并返回一个文件对象,该对象会缓存文件的状态和位置等信息。
  1. 进行文件读写操作:可以使用文件对象提供的方法进行文件读写操作,如 read()、write()、seek() 等。在进行文件读写操作时,文件指针会根据读写位置进行相应的移动。每次读写后,文件指针都会指向下一个位置。
  2. 关闭文件:在文件读写操作结束后,必须调用文件对象的 close() 方法关闭文件,以释放文件资源和内存。
  3. 释放文件对象:当文件对象被垃圾回收机制回收时,会自动调用 close() 方法释放文件资源。

总之,Python 文件操作的内部流程主要是通过打开文件、进行读写操作和关闭文件等步骤来完成的。在进行文件操作时,要注意及时关闭文件,避免因为文件资源未释放而导致程序出错。

插图:文件对象

资源回收与with上下文管理

  • with 的作用:with 能够保证代码在执行完成后,自动执行垃圾回收机制,并自动执行 close()来关闭文件
  • 手动回收:打开一个文件包含两部分资源:
    • 应用程序的变量f和操作系统打开的文件。
    • 在操作完毕一个文件时,必须把与该文件的这两部分资源全部回收
1. f.close() #回收操作系统打开的文件资源
2. del f #回收应用程序级的变量
其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件无法关闭,白白占用资源,
  • 使用 with 上下文管理器
    • python提供了 with 关键字来帮我们管理上下文,因为python自动的垃圾回收机制决定了我们无需考虑del f,或者在操作完毕文件后,很容易忘记使用f.close(),使用 with 关键字就可以解决这个问题
1.with open(r'file.txt', 'r') as f:
    # 执行文件读取操作
在 with 语句中打开文件时,当退出 with 语句块时,文件对象将自动调用 close() 方法,释放文件资源。
使用 with 就等于使用了 f=open,as 后面去跟的是别名,就可以说是句柄
 双引好外面跟上 r 是为了防止转义


2.语法格式:with open(r'a.txt','r',encoding='utf-8') as f:

    2.1.在执行完子代码块后,with 会自动执行f.close()
    	with open('a.txt','w') as f:
    		pass 
    
    2.2.可用用with同时打开多个文件,用逗号分隔开即可
        with open('a.txt','r') as read_f,open('b.txt','w') as write_f:  
        	data = read_f.read()
        	write_f.write(data)

二、Python 操作文件

Python 中的文件操作非常重要,可以用于读写文件、复制文件、删除文件等操作。

在 Python 中,使用内置的 open() 函数打开文件,并提供一些方法来进行读写、关闭等操作。

1.打开文件

使用 open() 方法可以打开一个文件,其语法为:

1.语法格式:open(‘文件路径’,‘读写模式’,‘字符编码’)
f = open('a.txt','r',encoding='utf-8')#打开文件
print(f.read())#操作文件
f.close()#关闭文件


2.f = open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
其中,file 是要打开的文件名(必须是一个字符串类型),mode 是文件打开的模式,缺省值为 'r'(只读模式)。

1.1文件操作模式

常见的文件打开模式包括:

  • t 模式:text 文本
    • r >>> rt
    • w >>> wt
    • a >>> at

1.它是以字符串位基本单位

2.它只能操作字符串形式

3. encoding参数必须写

  • b模式:bytes二进制模式
    • r >>> rb
    • w >>> wb
    • a >>> ab

1.b不能省略,必须写rb

2.它可以操作任意的数据类型:视频、音频、图片等都可以

3.encoding参数必须不能写

后面带➕代表,可读可写:r+、w+、a+

  • 'r':只读模式,文件存在时可读取文件内容。
1. r只读模式: 在文件不存在时则报错,文件存在文件内指针直接跳到文件开头
 with open('a.txt',mode='r',encoding='utf-8') as f:
     res=f.read() # 会将文件的内容由硬盘全部读入内存,赋值给res

2. 小练习:实现用户认证功能
 inp_name=input('请输入你的名字: ').strip()
 inp_pwd=input('请输入你的密码: ').strip()
 with open(r'db.txt',mode='r',encoding='utf-8') as f:
     for line in f:
         # 把用户输入的名字与密码与读出内容做比对
         u,p=line.strip('\n').split(':')
         if inp_name == u and inp_pwd == p:
             print('登录成功')
             break
     else:
         print('账号名或者密码错误')
  • 'w':只写模式,文件不存在时会创建该文件,文件存在时先清空文件,可向文件中写入数据。
3. w只写模式: 在文件不存在时会创建空文档,文件存在会清空文件,文件指针跑到文件开头
with open('b.txt',mode='w',encoding='utf-8') as f:
    f.write('你好\n')
    f.write('我好\n') 
    f.write('大家好\n')
    f.write('111\n222\n333\n')
强调:
 1 在文件不关闭的情况下,连续的写入,后写的内容一定跟在前写内容的后面
 2 如果重新以w模式打开文件,则会清空文件内容
  • 'a':追加模式,文件不存在时会创建该文件,文件存在时不会清空文件,可向文件中追加数据。用于在文件末尾添加内容
# a只追加写模式: 在文件不存在时会创建空文档,文件存在会将文件指针直接移动到文件末尾
 with open('c.txt',mode='a',encoding='utf-8') as f:
     f.write('44444\n')
     f.write('55555\n')
#强调 w 模式与 a 模式的异同:
# 1 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
# 2 不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后

# 小练习:实现注册功能:
 name=input('username>>>: ').strip()
 pwd=input('password>>>: ').strip()
 with open('db1.txt',mode='a',encoding='utf-8') as f:
     info='%s:%s\n' %(name,pwd)
     f.write(info)
  • 'x':独占写模式,文件不存在时会创建该文件,如果文件已经存在则 open() 方法会抛出 FileExistsError 异常。
  • 'b':二进制模式,可作为 'r'、'w'、'a' 或 'x' 模式的后缀使用,表示文件以二进制形式进行读写。用于读取或写入二进制数据,如图片、音频等
# 强调:b模式对比t模式
1、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便
2、针对非文本文件(如图片、视频、音频等)只能使用b模式
b模式:二进制
1.能操作任何的数据类型,eg:文本,音频,视屏
2.写法:rb ab wb  :此时的b不能省略
3.b模式的情况下encoding参数不能写,因为他都是字符编码的模式了encoding就没用了

rb:读写都是以二进制位单位
with open(r'a.jpeg','rb') as f:	b模式的话字符编码就不要了
print(f.read())	打印出一推二进制数
print(type(f.read())) # 输出结果为:<class 'bytes'>

wb:
with open(r'a.jpeg','rb',encoding='utf-8') as f:
f.write(b'你好')		你好前面必须加上b才可以打印出,不然出来的是乱码注释第一种编码方式
s.'你好'
f.write(s.encode(utf8))		这是第二种编码方式
"""wb写进去了也必须rb来读,然后后面还需要跟上decode去解码
print(f.read().decode('utf8'))
"""
按照字符或字节读取:要注意他读取的数据大小
with open(r'a.txt','a',encoding='utf-8') as f:
print(f.read(1))	当 r 模式下,read括号里面的数字代表的是字符,但是在 b 模式下read后面括号里面的代表的是字节
  • 't':文本模式,用于读取或写入文本文件的字符数据。
t 模式:如果我们指定的文件打开模式为r/w/a,其实默认就是rt/wt/at
 with open('a.txt',mode='rt',encoding='utf-8') as f:
     res=f.read() 
     print(type(res)) # 输出结果为:<class 'str'>
        
 with open('a.txt',mode='wt',encoding='utf-8') as f:
     s='abc'
     f.write(s) # 写入的也必须是字符串类型
    
 强调:t 模式只能用于操作文本文件,无论读写,都应该以字符串为单位,而存取硬盘本质都是二进制的形式,当指定 t 模式时,内部帮我们做了编码与解码
  • '+':读写模式,用于既能读取又能写入文件。
r+ w+ a+ :可读可写
在平时工作中,我们只单纯使用r/w/a,要么只读,要么只写,一般不用可读可写的模式
大前提: tb模式均不能单独使用,必须与r/w/a之一结合使用
t(默认的):文本模式
	1. 读写文件都是以字符串为单位的
	2. 只能针对文本文件
    3. 必须指定encoding参数
b:二进制模式:
   1.读写文件都是以bytes/二进制为单位的
   2. 可以针对所有文件
   3. 一定不能指定encoding参数

2.读写文件

在打开文件之后,可以使用 read()、write() 等方法对文件进行读写操作。

 1.读文件
    1.1.逐行读取文件内容
    with open('file.txt', mode='r') as f:
        for line in f:
            print(line)

    1.2.一次性读取所有内容
    with open('file.txt', mode='r') as f:
        content = f.read()
        print(content)
        '''read()是有缺陷的,如果打开文件特别大的时候就会打不开,会很慢。会导致内存溢出,因为他打开不会存在磁盘中,会先存在内存中''' 
    
    1.2.一次性读取所有行,并返回一个列表
    with open('file.txt', mode='r') as f:
        lines = f.readlines()
        print(lines)
    例子中使用了 open() 函数打开了文件,使用 with 语句操作文件,自动在处理结束后关闭文件。read() 方法将返回文件中的所有内容,可以指定读取的字符数。


2.强调:f.read()与f.readlines()都是将内容一次性读入内容,如果内容过大会导致内存溢出,若还想将内容全读入内存,则必须分多次读入,有两种实现方式:
    2.1.方式一
    with open('a.txt',mode='rt',encoding='utf-8') as f:
        for line in f:
            print(line) # 同一时刻只读入一行内容到内存中

    2.2.方式二
    with open('1.mp4',mode='rb') as f:
        while True:
            data=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
            if len(data) == 0:
                break
            print(data)
1.写入单行内容
with open('file.txt', mode='w') as f:
    f.write('hello, world!\n')
    """
    如果路径不存在,会新建一个文件
如果文件存在,会先清空文件中的内容,在进行写内容,就算不写东西用pass,也会清空,w模式就会直接清空
 w 模式只能写string类型

    """

2.写入多行内容
with open('file.txt', mode='a') as f:
    lines = ['line 1\n', 'line 2\n', 'line 3\n']
    f.writelines(lines)

3. a == apppen : 追加
with open(r'a.txt','a',encoding='utf-8') as f:
f.write('内容\n')
如果路径不存在,会新建一个文件
不会清空文件内容,但是不会换行,需要自己在内容后面加\n
多行数据:括号里不可能写多行数据,需要多个write如下:
    f.write('内容\n')
    f.write('内容\n')
    f.write('内容\n')
    f.write('内容\n')
r,w,a:只能读写文档,不能读写视频音频
 

3.关闭文件

在使用完文件后,必须使用 close() 方法关闭文件,以释放文件资源。
f = open('test.txt', 'r')
content = f.read()
f.close()

但是,在 Python 中也可以使用 with 语句来管理文件,会自动在处理结束后关闭文件,例如:
with open('test.txt', 'r') as f:
    content = f.read()
当 with 块执行结束后,Python 会自动关闭文件

4.其他文件操作

在 Python 中,还可以使用 os 模块和 shutil 模块进行文件相关的操作。例如,使用 os 模块删除一个文件:
import os

if os.path.exists('test.txt'):
    os.remove('test.txt')
else:
    print('The file does not exist.')

同时,os 模块还提供了其他各种文件操作方法,如重命名文件、获取文件属性等。
shutil 模块提供了对文件和目录的高级操作,例如复制文件、移动文件、创建目录等:

pythonCopy Codeimport shutil

# 复制文件
shutil.copyfile('source.txt', 'target.txt')

# 移动文件
shutil.move('source.txt', 'target.txt')

# 创建目录
os.makedirs('/path/to/new/dir')

5.对read方法做了优化

由于read是一次性读取完,可能会出现内存溢出的情况,所以,如何解决?

6.文件操作的所有内置方法

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None):打开文件并返回一个文件对象。
    1.file:要打开的文件名或路径。
    2.mode:文件打开模式,默认为 'r' 只读模式。其他常见模式有 'w' 只写模式、'a' 追加模式、'x' 独占模式、'b' 二进制模式和 't' 文本模式等。
    3.buffering:缓冲区大小或行缓冲标志(0 表示无缓冲,1 表示行缓冲,>1 表示缓冲区大小)。
    4.encoding:文件编码,用于读取和写入文本文件。默认为 None,此时使用系统的默认编码。
    5.errors:错误处理方式,用于指定解码错误的处理方式。默认为 None,此时使用默认策略。
    6.newline:行分隔符,用于写入文本文件时指定换行符。默认为 None,此时使用系统默认分隔符。
    7.closefd: 是否关闭文件描述符。默认为 True。
    8.opener:自定义文件打开器。
    9.file.close():关闭文件。

offset:相对于 whence 参数的偏移量,可正可负。
whence:可选参数,表示起始位置,0 表示文件头部,1 表示当前位置,2 表示文件尾部。默认值为 0。
file.truncate(size=None):截断文件至指定大小,如果未指定大小则截断到当前位置。

f.readable()  # 文件是否可读
f.writable()  # 文件是否可写
f.closed  # 文件是否关闭
f.encoding  # 如果文件打开模式为b,则没有该属性
f.flush()  # 立刻将文件内容从内存刷到硬盘
f.name

close()

1.打开文件
file = open("test.txt", mode='r')

2.关闭文件
file.close()

read() , readline() , readlines()

1.read()
    1.1.打开文件
    file = open("test.txt", mode='r')
    
    1.2.读取全部内容
    content = file.read()
    print(content)
    
    1.3.读取指定字节数
    content = file.read(10)#读取指定大小的内容,默认读取全部内容。
    print(content)
    
    1.4.关闭文件
    file.close()

2.readline()
    2.1.打开文件
    file = open("test.txt", mode='r')
    
    2.2.读取一行内容
    line = file.readline()#从文件中读取一行内容,如果指定参数则读取指定大小的内容
    print(line)
    
    2.3.读取多行内容
    while True:
        line = file.readline()
        if not line:
            break
        print(line)
    
    2.4.关闭文件
    file.close()

3.readlines()
	3.1.打开文件
    file = open("test.txt", mode='r')
    
    3.2.读取所有行并返回一个列表
    lines = file.readlines()
    print(lines)
    
    3.3.关闭文件
    file.close()
4.读模式
with open(r'a.txt','a',encoding='utf-8') as f:
print(f.readable())	判断是否可具备读的条件,就是看这个文件是否可读,返回bool值

write() , writelines() , writeable()判断是否具备写的条件,返回bool值

1.write()
    1.1.打开文件
    file = open("test.txt", mode='w')
    
    1.2.写入字符串
    file.write("Hello World\n")#向文件写入字符串,如果文件不存在会创建文件。
    file.write("Welcome to Python\n")
    
    1.3.关闭文件
    file.close()

2.writelines() 
    2.1打开文件
    file = open("test.txt", mode='w')
    
    2.2写入字符串列表
    lines = ["Hello World\n", "Welcome to Python\n"]#向文件写入一个序列的字符串。
    file.writelines(lines)
    
    2.3.关闭文件
    file.close()

3.writeable
with open(r'a.txt','a',encoding='utf-8') as f:
print(f.writeable())	判断是否具备写的条件,返回bool值

tell()

1.打开文件
file = open("test.txt", mode='r')

2.读取文件指针位置
position = file.tell()
print(position)

3.关闭文件
file.close()

truncate()

1.打开文件
file = open("test.txt", mode='r+')

2.截断文件到指定大小
file.truncate(10)

3.读取剩余内容
content = file.read()
print(content)

4.关闭文件
file.close()

flush() 把内存中的数据立刻刷到硬盘中,因为你一开始写的数据会存储在内存中如果发生断电数据会消失

1.打开文件
file = open("test.txt", mode='w')

2.写入字符串
file.write("Hello World\n")

3.刷新缓冲区
file.flush()

4.关闭文件
file.close()

文件的操作优化
print(f.flush())	把内存中的数据立刻刷到硬盘中,因为你一开始写的数据会存储在内存中如果发生断电数据会消失
"""文件句柄 f 支持for循环"""
with open(r'a.txt','a',encoding='utf-8') as f:
for line in f :
    print(line)		把文件里面的数据一行一行打印,以后读取文件的时候都要用for循环一行一行的去读取

三、主动控制文件内指针移动

移动方法:seek() 方法,seek() 方法用于将文件内指针移动到指定位置

seek() 方法语法:

file.seek(offset, whence)

参数说明:

  • offset : 需要移动的指针的相对偏移量,可以是正数、负数或零。
    • 正数:从左往右移动
    • 负数:从右往左移动
  • whence : 可选参数,默认值为0
    • 可选参数 0 : 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的,whence 参数可以不写,不写就是 0(tb 两种模式都支持)
    • 可选参数 1 : 该模式代表指针移动的字节数是以当前所在的位置为参照的(只支持 b 模式)
    • 可选参数 2 : 该模式代表指针移动的字节数是以文件末尾的位置为参照的(只支持 b 模式)
  • GBK编码:一个汉字占两个字节 。UTF-8编码:一个汉字占三个字节,不常用汉子占 4 个

强调:其中 0 模式可以在 t 或者 b 模式使用,而 1 跟 2 模式只能在 b 模式下用

1.打开文件
file = open("test.txt", mode="r")

2.移动指针到文件开头
file.seek(0)

3.读取前5个字符
content = file.read(5)
print(content)

4.移动指针到第10个字符处
file.seek(10, 0)#使用 seek(10, 0) 将文件指针移动到第10个字符处,然后使用 read() 读取从第10个字符开始的全部内容剩余内容
content = file.read()#读取从第10个字符开始,剩余的全部内容
print(content)

5.关闭文件
file.close()
# a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”各占3个字节)
abc你好

# 0模式的使用
with open('a.txt',mode='rt',encoding='utf-8') as f:
    f.seek(3,0)     # 参照文件开头移动了3个字节
    print(f.tell()) # 查看当前文件指针距离文件开头的位置,输出结果为3
    print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
    # 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败

with open('a.txt',mode='rb') as f:
    f.seek(6,0)
    print(f.read().decode('utf-8')) #输出结果为: 好
# 1模式的使用
with open('a.txt',mode='rb') as f:
    f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
    print(f.tell()) # 输出结果为:3
    f.seek(4,1)     # 从当前位置往后移动4个字节,而此时的当前位置为3
    print(f.tell()) # 输出结果为:7
# a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”各占3个字节)
abc你好

# 2模式的使用
with open('a.txt',mode='rb') as f:
    f.seek(0,2)     # 参照文件末尾移动0个字节, 即直接跳到文件末尾
    print(f.tell()) # 输出结果为:9
    f.seek(-3,2)     # 参照文件末尾往前移动了3个字节
    print(f.read().decode('utf-8')) # 输出结果为:好

# 小练习:实现动态查看最新一条日志的效果
import time
with open('access.log',mode='rb') as f:
    f.seek(0,2)
    while True:
        line=f.readline()
        if len(line) == 0:
            # 没有内容
            time.sleep(0.5)
        else:
            print(line.decode('utf-8'),end='')

四、 文件的修改

# 文件a.txt内容如下
张一蛋     山东    179    49    12344234523
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422

# 执行操作
with open('a.txt',mode='r+t',encoding='utf-8') as f:
    f.seek(9)
    f.write('<妇女主任>')
    
# 文件修改后的内容如下
张一蛋<妇女主任> 179    49    12344234523
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422

# 强调:
# 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
# 2、内存中的数据是可以修改的

1.文件修改方式一

# 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
with open('db.txt',mode='rt',encoding='utf-8') as f:
    data=f.read()

with open('db.txt',mode='wt',encoding='utf-8') as f:
    f.write(data.replace('kevin','SB'))#置换目标字符串.replace('要被置换对象','置换后新的字符',[,次数])

2.文件修改方式二

# 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
# 优点: 不会占用过多的内存
# 缺点: 在文件修改过程中同一份数据存了两份
import os

with open('db.txt',mode='rt',encoding='utf-8') as read_f,\
        open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
    for line in read_f:
        wrife_f.write(line.replace('SB','kevin'))

os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')

3.小练习:实现动态查看最新一条日志的效果

import time  # tail -f a.txt

with open('access.log', mode='rb') as f:
    f.seek(0, 2)  # 直接把光标移动到了末尾
    while True:
        line = f.readline()  # 读取一行数据
        if len(line) == 0:
            # 没有内容
            time.sleep(1)  # 睡眠 1 秒
        else:
            print(line.decode('utf-8'), end='')

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王献运

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值