文件操作

Golang文件操作 文件操作是指对计算机文件进行读取、写入、修改、删除和移动等操作的过程,它可以用于读取配置文件、存储日志、处理用户上传的文件等,Go中主要通过os和bufio包提供文件操作功能。文件在程序中是以流的形式进行操作的,我们把数据在数据源(文件)和程序(内存)之间经历的路径叫做流。其中数据从数据源到程序的路径叫做输入流,数据从程序到数据源的路径叫做输出流。基本介绍命令行参数是在运行程序时通过命令行传递给程序的参数,在Go中可以使用os包的Args变量来访问命令行参数。 阅读详情

本节主要内容:

1. 初识文件操作

2. 只读(r, rb)

3. 只写(w, wb)

4. 追加(a, ab)

5. r+读写

6. w+写读

7. a+写读(追加写读)

8. 其他操作方法

9. 文件的修改以及另一种打开⽂件句柄的方式

主要内容:

   一. 初识文件操作

   使用python来读写文件是非常简单的操作. 我们使用open()函数来打开一个文件, 获取到文件句柄. 然后通过文件句柄就可以进行各种各样的操作了. 根据打开⽅方式的不同能够执⾏行行的操 作也会有相应的差异.

    打开文件的方式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b 默认使用的是r(只读)模式

   二. 只读操作(r, rb)


f = open("护⼠士少妇嫩模.txt",mode="r", encoding="utf-8")

content = f.read()

print(content)

f.close()

   需要注意encoding表示编码集. 根据文件的实际保存编码进行获取数据, 对于我们而言. 更多的是utf-8.

   rb. 读取出来的数据是bytes类型, 在rb模式下. 不能选择encoding字符集.

f = open("护⼠士少妇嫩模.txt",mode="rb" )

content = f.read()

print(content)

f.close()

结果:

b'\xe6\xaf\x85\xe5\x93\xa5, \xe5\xa4\xaa\xe7\x99\xbd, wuse\n\xe5\x91\xb5\xe5\x91\xb5\n\xe6\x97\xa5\xe5\xa4\xa9'

   rb的作用: 在读取非文本文件的时候. 比如读取MP3. 图像. 视频等信息的时候就需要用到 rb. 因为这种数据是没办法直接显示出来的.  在后面我们文件上传下载的时候还会⽤用到. 还有我们看的直播. 实际上都是这种数据.

绝对路径和相对路径:

1. 绝对路路径:从磁盘根⽬目录开始⼀一直到⽂文件名.

2. 相对路路径:同⼀一个文件夹下的文件. 相对于当前这个程序所在的文件夹而言. 如果在同 一个文件夹中. 则相对路径就是这个文件名. 如果在上一层文件夹. 则要../


推荐大家使用相对路路径. 因为在我们把程序拷贝给别⼈人使用的时候. 直接把项目拷贝走 就能运行. 但是如果用绝对路径. 那还需要拷⻉贝外部的文件.

读取文件的方法:

1. read()  将文件中的内容全部读取出来. 弊端: 占内存. 如果文件过大.容易导致内存崩溃
f = open("../def/哇擦.txt", mode="r", encoding="utf-8")

content = f.read()

print(content)

结果: 友谊地久天长, 爱一点, 可惜我是水瓶座 一生中最爱
2. read(n) 读取n个字符. 需要注意的是. 如果再次读取. 那么会在当前位置继续去读而不是从头读, 如果使用的是rb模式. 则读取出来的是n个字节
f = open("../def/哇擦.txt", mode="r" encoding="utf-8")

content = f.read(3)

print(content)

结果:
友谊地


f = open("../def/哇擦.txt", mode="rb")

content = f.read(3)

print(content)

结果: b'\xe5\x8f\x8b'


f = open("../def/哇擦.txt", mode="r", encoding="utf-8")

content = f.read(3) content2 = f.read(3)

print(content) print(content2)

结果:

友谊地久天⻓长
3. readline() 一次读取一行数据, 注意: readline()结尾, 注意每次读取出来的数据都会有一 个\n 所以呢. 需要我们使用strip()方法来去掉\n或者空格
f = open("../def/哇擦.txt", mode="r", encoding="utf-8")

content = f.readline()

content2 = f.readline()

content3 = f.readline()

content4 = f.readline()

content5 = f.readline()

content6 = f.readline()

print(content)

print(content2)

print(content3)

print(content4)

print(content5)

print(content6) 结果:

友谊地久天⻓长, 爱⼀一点,
可惜我是⽔水瓶座
一生中最爱
4. readlines()将每一行形成一个元素, 放到一个列表中. 将所有的内容都读取出来. 所以也是容易出现内存崩溃的问题.不推荐使⽤
f = open("../def/哇擦.txt", mode="r", encoding="utf-8")

lst = f.readlines()

print(lst)

for line in lst:

   print(line.strip())
5. 循环读取. 这种方式是最好的. 每次读取一行内容.不会产生内存溢出的问题. 
f = open("../def/哇擦.txt", mode="r", encoding="utf-8")

for line in f:

   print(line.strip())
注意: 读取完的文件句柄一定要关闭   f.close()

三. 写模式(w, wb)

写的时候注意. 如果没有文件. 则会创建文件, 如果文件存在. 则将原件中原来的内容删除,

写入新内容

f = open("⼩小娃娃", mode="w", encoding="utf-8")

f.write("⾦金金⽑毛狮王")

f.flush()    # 刷新. 养成好习惯

f.close()
尝试读一读

f = open("⼩小娃娃", mode="w", encoding="utf-8")

f.write("⾦金金⽑毛狮王")

f.read()    # not readable 模式是w. 不可以执行读操作

f.flush()

f.close()
wb模式下. 可以不指定打开文件的编码. 但是在写文件的时候必须将字符串转化成utf-8的 bytes数据

f = open("⼩小娃娃", mode="wb")

f.write("⾦金金⽑毛狮王".encode("utf-8"))

f.flush()

f.close()


四. 追加(a, ab)

   在追加模式下. 我们写入的内容会追加在文件的结尾.
f = open("⼩小娃娃", mode="a", encoding="utf-8")

f.write("麻花藤的最爱")

f.flush()

f.close()

   ab模式自⼰己试一试就好了了

五. 读写模式(r+, r+b)

   对于读写模式. 必须是先读. 因为默认光标是在开头的. 准备读取的. 当读完了了之后再进行写入.

我们以后使⽤用频率最⾼高的模式就是 r+

正确操作是:

f = open("⼩小娃娃", mode="r+", encoding="utf-8")

content = f.read()

f.write("麻花藤的最爱")

print(content) f.flush()

f.close()

结果: 正常的读取之后, 写在结尾
错误操作:

f = open("⼩小娃娃", mode="r+", encoding="utf-8")

f.write("哈哈")

content = f.read()

print(content)

f.flush()

f.close()

结果: 将开头的内容改写成了"哈哈", 然后读取的内容是后面的内容. 


所以记住: r+模式下. 必须是先读取. 然后再写入

 六. 写读(w+, w+b)

   先将所有的内容清空. 然后写入. 最后读取. 但是读取的内容是空的, 不常用

f = open("⼩小娃娃", mode="w+", encoding="utf-8")

f.write("哈哈")

content = f.read()

print(content)

f.flush()

f.close()
    有人会说. 先读不就好了么? 错. w+ 模式下, 一开始读取不到数据. 然后写的时候再将原来的内容清空. 所以, 很少用.

    七. 追加读(a+)

   a+模式下, 不论先读还是后读. 都是读取不到数据的.

f = open("⼩小娃娃", mode="a+", encoding="utf-8")

f.write("⻢马化腾")

content = f.read()

print(content)

f.flush()

f.close()
还有⼀一些其他的带b的操作. 就不多赘述了了. 就是把字符换成字节. 仅此⽽而已

八. 其他相关操作

1. seek(n) 光标移动到n位置,  注意, 移动的单位是byte. 所以如果是UTF-8的中⽂文部分要是3的倍数.

       通常我们使用seek都是移动到开头或者结尾.

        移动到开头: seek(0)

       移动到结尾: seek(0,2)

 seek的第二个参数表示的是从哪个位置进行偏移, 默认是0,  表示开头, 1表示当前位置, 2表示结尾
f = open("⼩小娃娃", mode="r+", encoding="utf-8")

f.seek(0)   # 光标移动到开头

content = f.read()  # 读取内容, 此时光标移动到结尾

print(content)

f.seek(0)   # 再次将光标移动到开头

f.seek(0, 2)    # 将光标移动到结尾

content2 = f.read()  # 读取内容. 什么都没有

print(content2)

f.seek(0)   # 移动到开头

f.write("张国荣")  # 写入信息. 此时光标在9  中文3 * 3个 = 9

f.flush()

f.close()
2. tell()

使用tell()可以帮我们获取到当前光标在什么位置
f = open("⼩小娃娃", mode="r+", encoding="utf-8")

f.seek(0)   # 光标移动到开头

content = f.read()  # 读取内容, 此时光标移动到结尾
print(content)

f.seek(0)   # 再次将光标移动到开头

f.seek(0, 2)    # 将光标移动到结尾

content2 = f.read()  # 读取内容. 什么都没有

print(content2

) f.seek(0)   # 移动到开头

f.write("张国荣")  # 写入信息. 此时光标在9  中⽂文3 * 3个 = 9

print(f.tell())  # 光标位置9

f.flush()

f.close()
3. truncate() 截断文件
f = open("⼩小娃娃", mode="w", encoding="utf-8")

f.write("哈哈")   # 写⼊入两个字符

f.seek(3)   # 光标移动到3, 也就是两个字中间

f.truncate()    # 删掉光标后⾯面的所有内容

f.close()
f = open("⼩小娃娃", mode="r+", encoding="utf-8")

content = f.read(3)  # 读取12个字符

f.seek(4)

print(f.tell())

f.truncate()    # 后⾯面的所有内容全部都删掉 #

print(content)

f.flush()

f.close()
    深坑请注意:

          在r+模式下. 如果读取了了内容. 不论读取内容多少. 光标显示的是多少. 再写入或者操作文件的时候都是在结尾进行的操作. 所以如果想做截断操作. 记住了. 要先挪动光标. 挪动到你想要截断的位置. 然后再进行截断 关于truncate(n), 如果给出了n. 则从开头开头进行截断, 如果不给n, 则从当前位置截断. 后⾯的内容将会被删除


九. 修改文件以及另一种打开文件的方式

   文件修改: 只能将文件中的内容读取到内存中, 将信息修改完毕, 然后将源文件删除, 将新文件的名字改成老文件的名字.

# ⽂文件修改

import os
with open("⼩小娃娃", mode="r", encoding="utf-8") as f1,\     open("⼩小娃娃_new", mode="w", encoding="UTF-8") as f2:    content = f1.read()    new_content = content.replace("冰糖葫芦", "⼤大⽩白梨梨")    f2.write(new_content) os.remove("⼩小娃娃")    # 删除源⽂文件 os.rename("⼩小娃娃_new", "⼩小娃娃")     # 重命名新⽂文件    弊端: ⼀一次将所有内容进⾏行行读取. 内存溢出. 解决⽅方案: ⼀一⾏行行⼀一⾏行行的读取和操作

import os

with open("小娃娃", mode="r", encoding="utf-8") as f1,\

        open("小娃娃_new", mode="w", encoding="UTF-8") as f2:

   for line in f1:

       new_line = line.replace("⼤大⽩白梨梨", "冰糖葫芦")

       f2.write(new_line) os.remove("⼩小娃娃")    # 删除源⽂文件

os.rename("⼩小娃娃_new", "⼩小娃娃")     # 重命名新⽂文件

弊端: 一次将所有内容进行读取. 内存溢出. 解决方案: 一行一行的读取和操作 

import os

with open("⼩小娃娃", mode="r", encoding="utf-8") as f1,\

        open("⼩小娃娃_new", mode="w", encoding="UTF-8") as f2:

        for line in f1:

              new_line = line.replace("⼤大⽩白梨梨", "冰糖葫芦")

              f2.write(new_line)

os.remove("⼩小娃娃")    # 删除源⽂文件

os.rename("⼩小娃娃_new", "⼩小娃娃")     # 重命名新⽂文件

Qt文件操作 Qt提供了跨平台的文件操作能力,核心类包括QIODevice(I/O设备抽象基类)、QFile(本地文件读写)、QTemporaryFile(临时文件)等。QFile支持随机访问,提供文件打开、读写、关闭等功能,可与QTextStream或QDataStream配合使用。文件操作模式包括ReadOnly、WriteOnly、ReadWrite等,支持文本和二进制处理。此外,QFileInfo可获取文件属性信息,QFile还提供静态方法实现文件删除、重命名等操作。开发者需注意路径分隔符使用"/&qu 阅读详情

相关推荐

Rust语言的文件操作

本文介绍了Rust语言中基本的文件操作,包括创建文件、读取文件、写入文件和删除文件。我们通过结合具体的代码示例,详细讲解了如何使用Rust的标准库来完成这些操作。Rust的设计哲学注重安全性和并发性,这使得在进行文件操作时能够有效防止常见的错误,同时提高了代码的可读性和可维护性。随着我们对Rust语言的深入学习,可以探索更多高级功能,例如文件的异步操作、目录的操作以及文件系统的其他操作。希望本文能为你在Rust编程的道路上提供一些帮助和灵感!

2501_90199847的博客 1470

最常用计算机文件后缀名,windows系统文件后缀(扩展名)简单介绍,电脑知识普及...

话说文件“后缀”,应该都有所了解吧?其意义就是表示一个文件的类型。不同类型的文件有不同的作用,同时也必须用不同的工具才能打开。比如常见的.txt、.mp3、.jpg、.rar这些就是后缀。每个文件的后面都是以.xxx结尾的,不信自己看看。相信大家都知道前面几个几个后缀代表的是什么文件类型吧?.txt代表的是文本文档,也就是用记事本创建的,通常手机大多支持这种文件格式。.jpg最常用的图片格式,但是...

weixin_39540023的博客 2951

Lua语言的文件操作

"r": 只读模式。如果文件不存在,则返回nil。"w": 只写模式。如果文件存在,则会被清空;如果文件不存在,则会创建新文件。"a": 追加模式。如果文件存在,则数据将写入到文件的末尾;如果文件不存在,则会创建新文件。"r+": 读写模式。如果文件不存在,则返回nil。"w+": 读写模式。如果文件存在,则会被清空;如果文件不存在,则会创建新文件。"a+": 读写模式,数据将写入文件末尾。Lua语言的文件操作简单而强大,灵活的I/O功能使得开发者能够高效地处理文本数据。

nsp202502的博客 1684

f.read()函数详解

用read函数读取两次,就变成了空字符串。 问题:用read()函数读取文件两次,就变成空字符串 代码示例: #文件 my_file 内存的是 'a b c' with open ('my_file', 'r') as f: a = f.read() b = f.read().split() print a # a b c print b # [] 原因:python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。再来个re

Traversal-chen的博客(hpudcd@163.com) 8314

TypeScript语言的文件操作

在这个简单的应用中,我们将用户上传的文件内容读取后显示在页面上,用户还能够通过点击按钮下载这些内容。通过这样的示例,我们能够清晰地看到TypeScript在文件操作中的应用场景。本文对TypeScript的文件操作进行了全面的探讨,包括客户端和服务器端的文件操作。我们不仅介绍了如何读取、写入和下载文件,还强调了错误处理的重要性。通过实际示例代码,读者可以更容易地理解如何在自己的项目中使用TypeScript进行文件处理。希望这篇文章能对你在TypeScript的学习和应用中有所帮助!

gebilaowang2401的博客 632

Kotlin语言的文件操作

本文详细介绍了Kotlin语言中的文件操作,包括基本的文件读写、文件夹操作、异常处理以及使用NIO包提高文件操作效率的方法。同时,我们还学习了如何遍历和过滤文件。Kotlin简洁和强大的特性使这些操作变得相对简单和直观。掌握这些文件操作后,我们可以在Kotlin中轻松处理文件相关的任务,并构建更加复杂的应用程序。无论是读写日志文件、处理配置文件,还是实现数据的持久化,文件操作都是开发者必备的技能之一。希望本文能够帮助读者更好地理解和应用Kotlin的文件操作。

2401_90032081的博客 1196

Python文件读写

在使用python编程时,经常会遇到读写文件的操作。 很多童鞋困扰于读写文件的各种模式(如阅读、写入、追加等),以及搞不清open、read、readline、readlines、write等方法的使用。 这篇文章就是要告诉你Python文件读写的所有秘密! 01、open函数 如果你想用python读取文件(如txt、csv等),第一步要用open函数打开文件。 open()是python的内置函数,它会返回一个文件对象,这个文件对象拥有read、readline、write、close等.

ytp552200ytp的博客 1982

wbj

j

关于文件操作的几种常用方式,总结如下,包括csv的一点用法和理解(后续总结)

关于文件操作的几种常用方式,总结如下,包括csv的一点用法和理解(后续总结)

CHENGGONG2021的博客 1425

Python OpenCV基于颜色通道分离法去除图片中的红色印章

最近一段时间的工作都是研究如何去除图片中的红色印章,在网上查找了大量的大佬写过的方法,发现大多数是采取颜色通道分离法来做,并且效果还不错。站在前人的肩膀上,我又做了些许调整,谈不上是改进,但是能应对更对的情况总还是好的,特此记录。 拿发票做例子,印章相较于其它部分最大的不同就是印章是红色的,而其它部分不是(这是一句废话)。 那么第一步当然就是将红色分离出来,这一步可以采用Python第三方库OpenCV里的 cv2.split()方法,该方法是把RGB图像的三个通道拆分开来,得...

wl_Honest的博客 1万+

【Seurat绘图进阶】从参数调优到美学定制:解锁DimPlot与FeaturePlot的隐藏技巧

本文深入探讨了Seurat包中DimPlot与FeaturePlot的进阶使用技巧,旨在解决单细胞数据可视化中的常见痛点。通过参数调优(如order、shuffle、raster)、颜色美学定制(使用RColorBrewer、viridis配色)以及性能优化(栅格化处理),并结合scCustomize包与patchwork排版,帮助用户将基础图表提升为信息清晰、可直接用于论文发表的出版级可视化结果。

lake5的博客 629

c++文件操作大全

c++文件操作大全 基于C的文件操作   在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef struct {   int level;           /* fill/empty level of buffer */...

hbqjzx的专栏 7万+

你不必懂AI,但必须会用AI:写给所有焦虑中的职场人

AI时代不必焦虑学技术,关键在于用AI解决实际问题。文章指出,99%的人只需成为AI使用者而非建造者,核心竞争力在于结合业务痛点运用AI工具提升效率。与其盲目学习工具,不如梳理工作流程,识别可优化环节,让AI赋能重复性、标准化任务。行业经验与AI工具的结合才是真正的职场护城河。建议从具体工作场景出发,寻找匹配的AI解决方案,迈出应用第一步。

hundred98的博客 716

C++文件操作之一 :基于C的文件操作

在编程的过程中,文件的操作是一个经常用到的问题,在C++中,可以使用多种方法对文件操作,下面我就按以下几个部分对此作详细介绍,就是:1、基于C的文件操作;2、基于C++的文件操作;3、基于WINAPI的文件操作;4、基于BCB库的文件操作;5、特殊文件的操作。一、基于C的文件操作 A.  C语言继承下来的文件操作:  在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面

z2care的专栏 4201

01-FreeSWITCH 的安装、部署、配置以及可能遇到的问题和解决方法

一文让您了解从FreeSWITCH 的安装、部署、配置、可能遇到的问题及解决方法。一切从实际项目出发,以工程应用为目的。

秋风的博客 2127

Windows-Anaconda3+TensorFlow安装教程

测试环境:win10-64位和win7-64位 (系统必须是64位,因为TensorFlow目前只支持64位) 一、安装Anaconda3 1.下载Anaconda3 Anaconda官网链接:link 这里我们选择Windows版本,python3.6-version-64位,如下图所示。 2.下载完成之后,点击安装Anaconda3 注意:安装过程中要选择添加环境变量,如图 待安装完成...

DoctorCuiLab的博客 3086

Python中对基本文件操作

Python中对基本文件操作,一起来学习吧(一起努力,咱们顶峰相见)

精益求精,永无止境,永远在路上! 7856

ESP32-P4开发板实战:从零配置VSCode环境到点亮MIPI-DSI屏幕(避坑指南)

本文详细介绍了ESP32-P4开发板在VSCode环境下的配置流程,包括SDK安装、idf_component.yml依赖管理,以及MIPI-DSI屏幕驱动的实现方法。通过实战指南帮助开发者避开常见配置陷阱,快速完成从环境搭建到屏幕点亮的全流程,适用于物联网和嵌入式开发场景。

pp12345的博客 742

C++文件操作

不要以文本模式打开二进制文件,也不要用行的方法操作二进制文件,可能会破坏二进制数据文件的格式,也没有必要。D:\study\编程\C语言\学习\文件操作\test.c。dir参数用于对文件流指针的定位操作上,代表搜索的起始位置。seekg:设置输入文件流的文件流指针位置。在程序运行结束后将不会被记录保存。存放在硬盘上的数据就是文件了。pos:新的文件流指针位置值。文件标识常被称为文件名。dir:搜索的起始位置。数据持久化的两种方式。off:需要偏移的值。

2303_80087291的博客 2081

避坑指南:vue-print-nb打印隐藏元素与空白页的那些事儿

本文深入解析了使用vue-print-nb插件时,打印出现空白页及隐藏元素问题的根本原因与解决方案。核心在于理解浏览器打印原理,并通过CSS媒体查询精准控制样式。文章提供了从重置根元素高度、处理隐藏元素到控制分页的完整避坑指南,帮助开发者彻底解决打印样式难题。

weixin_29008691的博客 437

Far planner代码系列(2)

graph_decoder系列(2) 承接上文 我们接着来看decoder_node.cpp的代码部分 void GraphDecoder::Init() { /* initialize subscriber and publisher */ //graph_sub_ 订阅节点/robot_vgraph 其类型是visibility_graph_msg/Graph的消息 graph_sub_ = nh.subscribe("/robot_vgrap...

博客 1534

【Qt】—— Qt文件操作

Qt文件操作

m0_56069910的博客 2122

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Python 文件操作详解

本文全面介绍了Python文件操作的核心知识,包括基本流程、打开模式、常用方法和实用场景。文章详细对比了各种操作模式的差异,并提供了大量代码示例,特别推荐使用with语句自动处理文件关闭,是掌握Python文件处理的实用指南。

x15514104477的博客 1095

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

JavaScript 文件操作指南

本文旨在帮助您理解 JavaScript 中的文件操作,涵盖文件读取、写入、创建、删除等基本操作,以及更高级的异步操作、流式处理和错误处理等主题。​File对象继承自Blob。除了Blob方法和属性外,File对象还有name和属性,以及从文件系统读取的内部功能。我们通常从用户输入如或拖放事件来获取File对象。FileReader字符串(readAsTextdata url,base-64 编码(但是,在很多情况下,我们不必读取文件内容。

爱蹦跶的全栈大A阿 5359

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

python文件操作

python对文件的常见操作以及代码演示

。 1841
上一篇: 基本数据类型-集合
下一篇: 函数的参数
raw_recruit0302
博客等级 码龄8年 30粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值