C#实现文本文件直接读取与打印的完整示例

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:C#编程中,载入并打印文本文件是一个常用功能。本实例演示了如何使用 System.IO System.Drawing.Printing 命名空间下的类来实现这一功能。首先,通过 StreamReader 类读取TXT文件内容;其次,利用 PrintDocument 类及其事件处理器 PrintPage 来实现打印逻辑;最后,通过Windows Forms应用程序提供用户界面,让用户选择文件并触发打印。此外,还需确保系统中安装有打印机,并进行错误处理和用户界面优化。

1. C#文本文件载入打印示例概述

在这一章节中,我们将对C#中涉及文本文件载入和打印功能的整个流程进行高层次的介绍。我们会从一个简单的例子出发,该例子演示了如何在C#中加载文本文件内容并将其发送至打印机进行打印。这个过程不仅涉及到文件的读取,还涵盖了用户界面的设计、打印机的选择与配置,以及最后的打印输出。通过本章的介绍,读者将获得一个整体的视角,对后续章节的深入学习建立起初步的理解和期待。本章内容将为读者展示一个全局性的示例,而后续章节将分别深入解析每个步骤的具体实现细节和技巧。

2. 文件操作和System.IO命名空间

2.1 文件操作基础

2.1.1 文件读取的必要性与实现方式

在日常的软件开发中,从简单的文本编辑器到复杂的数据处理系统,文件读取是一项不可或缺的功能。其必要性体现在数据持久化和信息共享两大方面。实现文件读取的方式多种多样,从最基础的文件流操作到高级的异步读取,每种方法都有其适用场景和优势。

在C#中,文件读取可通过多种类和方法实现。最基本的是使用 System.IO 命名空间中的 File 类,它提供了静态方法来完成基本的文件读取任务,如 File.ReadAllText() File.ReadAllLines() 方法可以方便地读取文本文件的全部内容。

2.1.2 文件路径和文件系统的理解

文件路径是指向文件系统中具体文件或目录位置的字符串。理解文件路径对于文件操作至关重要,特别是在涉及文件读取和写入时。C#中主要通过 FileInfo 类和 DirectoryInfo 类来操作文件和目录路径。

文件路径分为绝对路径和相对路径。绝对路径是从根目录开始到目标文件或目录的完整路径,相对路径则是相对于当前工作目录的路径。路径的正确性直接影响到文件操作的成败,因此路径验证和异常处理是实现稳健文件操作的基础。

// 示例代码:读取文本文件内容
using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            string filePath = @"C:\path\to\your\file.txt";
            string content = File.ReadAllText(filePath);
            Console.WriteLine(content);
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: " + e.Message);
        }
    }
}

在上述代码示例中,使用 File.ReadAllText 方法读取指定文件路径下的文本文件,并输出其内容到控制台。

2.2 System.IO命名空间详解

2.2.1 命名空间中关键类的作用与应用

System.IO 命名空间下包含多个处理文件和目录的类,是进行文件操作的核心部分。例如:

  • FileInfo : 提供创建、复制、删除、移动和打开文件的实例方法,并帮助确定文件的大小、创建时间、访问时间等属性。
  • DirectoryInfo : 允许列出目录中的文件和子目录,并创建、删除或移动目录。
  • FileStream : 提供对文件或文件流的读写访问。
  • StreamReader StreamWriter : 分别用于读取和写入字符数据。

使用这些类,开发者可以根据具体需求选择合适的文件操作方式。例如,对于需要逐行读取的大型文本文件, StreamReader 是一个很好的选择。

2.2.2 文件操作类(如FileInfo, File等)的具体用法

FileInfo File 类是C#中文件操作最常用的两个类。它们提供了不同的方法来处理文件。

FileInfo 是一个表示文件信息的类,它包含文件的详细信息,如文件名、大小、创建和修改时间等。以下示例展示了如何使用 FileInfo 来获取文件属性。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = @"C:\path\to\your\file.txt";
        FileInfo fileInfo = new FileInfo(filePath);
        Console.WriteLine("File name: " + fileInfo.Name);
        Console.WriteLine("File size: " + fileInfo.Length + " bytes");
        Console.WriteLine("Creation date: " + fileInfo.CreationTime);
        Console.WriteLine("Last access time: " + fileInfo.LastAccessTime);
    }
}

File 类提供静态方法来对文件执行操作,例如复制、移动、删除和读取。 File 类方法通常执行简单直接的操作,适用于不需要文件详细信息的场景。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string sourcePath = @"C:\path\source.txt";
        string destinationPath = @"C:\path\destination.txt";
        File.Copy(sourcePath, destinationPath);
        Console.WriteLine("File copied successfully.");
    }
}

在这段代码中,使用 File.Copy 方法简单地将一个文件从源路径复制到目标路径。

总的来说, System.IO 命名空间中的文件操作类为开发者提供了强大的工具集来处理文件和目录,无论是简单的读写操作还是复杂的文件属性管理。

3. StreamReader类在文件载入中的应用

3.1 StreamReader类介绍

3.1.1 StreamReader的工作原理

StreamReader 类是.NET框架中用于读取字符数据流的类。它通常用于从文件或网络流中读取文本数据。当创建 StreamReader 实例时,它会接受一个 Stream 对象作为数据源,这个数据源可以是文件、内存缓冲区甚至是网络资源。 StreamReader 使用编码器将字节流转换成字符流,从而使得从文件中读取文本变得更加直接和简单。

StreamReader 提供了多种方法来读取数据,如 Read ReadLine ReadToEnd 等。它支持逐字符、逐行或一次性读取整个流内容到内存中。这使得 StreamReader 非常灵活,能够适应不同的文件处理场景。

3.1.2StreamReader与文件流的关系

在.NET中, Stream 类是一个抽象类,它定义了一个字节序列,可以异步或同步地读取和写入字节。 FileStream 类继承自 Stream ,专门用于文件操作,提供了读写文件的方法。而 StreamReader 是建立在 Stream 基础上的一个抽象,它使得读取字符数据变得简单,不需要直接操作字节流。

StreamReader FileStream 结合使用时,可以创建一个从文件中读取文本数据的高效途径。 StreamReader 封装了 Stream ,处理了字符编码等问题,因此开发者只需要关注于读取和处理字符数据。

3.2 实践:使用StreamReader读取文本文件

3.2.1 创建StreamReader对象

在使用 StreamReader 之前,必须先创建一个 FileStream 实例,因为 StreamReader 需要一个 Stream 对象作为参数。下面是一个示例代码,展示了如何创建一个 StreamReader 对象来读取一个文本文件:

using System.IO;

class Program
{
    static void Main()
    {
        // 指定要读取的文件路径
        string filePath = @"C:\example.txt";

        // 使用FileStream来打开文件
        using(FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            // 创建StreamReader实例来读取FileStream
            using(StreamReader streamReader = new StreamReader(fileStream))
            {
                // 读取内容的逻辑将在这里实现
                string line;
                while((line = streamReader.ReadLine()) != null)
                {
                    // 输出读取到的每一行
                    Console.WriteLine(line);
                }
            }
        }
    }
}

3.2.2 读取数据与异常处理

在上面的代码中,我们使用 using 语句来确保 StreamReader FileStream 对象在使用完毕后能够正确地被释放。这是一种资源管理的最佳实践,特别是在涉及到文件操作时。使用 StreamReader.ReadLine() 方法,我们可以逐行读取文件内容,直到文件末尾。

异常处理是文件操作中的重要环节,因为文件不存在、路径错误或其他I/O问题都可能引发异常。处理异常通常涉及捕获特定的异常类型,并为可能出现的错误提供合适的处理逻辑。下面是带有异常处理逻辑的代码示例:

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 指定要读取的文件路径
        string filePath = @"C:\example.txt";

        try
        {
            // 尝试打开文件并读取内容
            using(FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                using(StreamReader streamReader = new StreamReader(fileStream))
                {
                    string line;
                    while((line = streamReader.ReadLine()) != null)
                    {
                        // 输出读取到的每一行
                        Console.WriteLine(line);
                    }
                }
            }
        }
        catch(FileNotFoundException ex)
        {
            // 文件未找到的异常处理
            Console.WriteLine("文件未找到,请检查路径是否正确。");
        }
        catch(IOException ex)
        {
            // 其他I/O异常处理
            Console.WriteLine("读取文件时发生错误。");
        }
    }
}

在上述代码中,我们使用 try-catch 语句来处理文件操作可能抛出的异常。首先尝试打开文件并读取内容,如果在执行过程中遇到 FileNotFoundException IOException ,则捕获这些异常并给出相应的错误提示。这样可以在出错时提供有用的反馈信息,而不是让程序意外崩溃。

4. 打印功能的实现

4.1 打印基础知识

4.1.1 打印过程的理解

在计算机科学中,打印功能允许用户将电子文档或图像转换为纸张上的物理输出。这一过程涉及多个组件和步骤,包括文档的生成、格式化、传输以及在打印机上的最终渲染。

  1. 文档生成 :在计算机中,用户通过文字处理软件、浏览器或其他应用程序生成或选择需要打印的文档。
  2. 格式化 :文档必须被转换成打印机能够理解的语言,这通常是通过打印机驱动程序完成的,它将文档格式转换成打印机所支持的打印语言(例如PCL或PostScript)。
  3. 传输 :格式化后的打印任务通过适当的通信协议发送到打印机。常见的协议包括TCP/IP或USB。
  4. 打印任务执行 :打印机接收命令后,开始纸张进给、墨盒工作以及图像绘制等物理过程。
  5. 输出 :最终的打印输出结果是文档内容在纸张上的视觉呈现。

4.1.2 打印技术的选择与对比

现代打印技术多种多样,每一种都有其特定的使用场景和优势。以下是一些常见的打印技术及其对比:

  • 喷墨打印 :适合家庭和办公室使用,打印成本相对较低,但速度可能不及激光打印机。
  • 激光打印 :速度快、质量高,适用于大量文档打印的环境,但其设备和耗材成本较高。
  • 热敏打印 :通常用于收据和标签打印,速度快但无法打印彩色。
  • 3D打印 :通过逐层堆叠材料来制造三维物体,技术逐渐成熟,但打印速度和成本问题仍待解决。

在选择打印技术时,应考虑打印需求、打印量、打印质量、成本及速度等因素。

4.2 System.Drawing.Printing命名空间介绍

4.2.1 命名空间中关键类的简介

System.Drawing.Printing 是一个强大的命名空间,它提供了丰富的类,用于实现和控制打印任务。其中,最关键的类包括:

  • PrintDocument类 :这是进行打印任务的核心类,它封装了打印文档所需的所有功能。可以设置打印参数、添加打印事件处理器、开始打印任务等。
  • PrintPageEventArgs类 :表示每次打印页面时发生的事件的数据。它包含了关于打印页面的详细信息,如页面大小、打印方向等,并用于绘制页面内容。
  • PrintPreviewControl类 :提供一个可配置的打印预览界面,使用户能在实际打印前查看文档的打印效果。

4.2.2 PrintDocument类的作用

PrintDocument 类是实现打印功能的关键。它提供了一系列属性和事件,使得开发者可以自定义打印任务的执行。主要功能包括:

  • Print()方法 :启动打印过程。
  • PrintPage事件 :在打印每一页时触发,开发者可以在此事件中定义页面内容的绘制逻辑。
  • PrinterSettings属性 :允许访问和修改打印机设置,例如打印机名称、打印质量、纸张来源等。

PrintDocument 类使开发人员能够控制打印的各个方面,实现丰富的打印功能。

4.2.2.1 PrintDocument类的代码实现

using System;
using System.Drawing.Printing;
using System.Windows.Forms;

public class CustomPrintDocument : PrintDocument
{
    protected override void OnPrintPage(PrintPageEventArgs e)
    {
        // 在这里定义打印页面的内容
        base.OnPrintPage(e);
        // 这里只是示例,绘制一个简单的文本框
        using (Font font = new Font("Arial", 12))
        {
            e.Graphics.DrawString("Hello, this is a custom print job!", font, Brushes.Black, 100, 100);
        }
    }
}

在上面的代码示例中,创建了一个继承自 PrintDocument 的类,并重写了 OnPrintPage 方法。在这个方法里,我们使用了 Graphics.DrawString 方法绘制了一个简单的文本框。这只是一个简单的开始,实际应用中,根据需要可以在该事件中添加更复杂的绘制逻辑。

通过以上代码,可以开始实现自定义的打印功能。在实际的应用开发中,还可以根据需要添加更多的逻辑来处理各种复杂的打印任务,如添加页眉页脚、图片、复杂图表等。

5. PrintDocument类和PrintPage事件处理器

在C#中, System.Drawing.Printing 命名空间提供了用于打印文档的类和接口。其中, PrintDocument 类是一个非常重要的类,它表示要打印的文档,并且可以通过自定义事件来控制打印过程。 PrintPage 事件处理器是与之紧密相关的一个事件,它定义了打印页面的内容和格式。

5.1 PrintDocument类的使用方法

PrintDocument 类是打印操作的核心类,通过它能够初始化打印任务并处理打印文档的各个方面。

5.1.1 创建PrintDocument实例

在开始打印之前,首先需要创建一个 PrintDocument 的实例。

using System.Drawing.Printing;

// ...

private void btnPrint_Click(object sender, EventArgs e)
{
    PrintDocument printDocument = new PrintDocument();
    printDocument.Print();
}

上述代码片段中,我们创建了一个 PrintDocument 的实例,并且通过调用 Print 方法开始打印。需要注意的是,这个方法会触发默认打印机的打印对话框。如果需要更多的控制,可以通过监听 PrintPage 事件来实现。

5.1.2 设置打印参数与自定义打印行为

PrintDocument 类允许开发者在打印开始之前配置打印参数,比如打印页边距、打印方向等。

printDocument.DefaultPageSettings.PaperSize = new PaperSize("Custom", 800, 1200);
printDocument.DefaultPageSettings.Margins = new Margins(20, 20, 20, 20);

上述代码设置了打印纸张大小和页边距。 PaperSize Margins 都是 PageSettings 类的成员, PageSettings 则是 PrintDocument 的一个属性。

5.2 PrintPage事件处理器的实现

PrintPage 事件处理器对于定制打印页面的内容和格式至关重要。

5.2.1 事件处理器的作用与重要性

PrintPage 事件在打印页被发送到打印机之前触发。通过提供自定义的 PrintPageEventHandler 实现,可以在打印之前修改页面的布局和内容。

private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
    e.Graphics.DrawString("Hello, World!", new Font("Arial", 12), Brushes.Black, new PointF(100, 100));
}

在这段示例代码中,我们使用 Graphics 对象的 DrawString 方法来绘制文本 "Hello, World!" 到打印页上,其中 PointF 定位了字符串的起始位置。

5.2.2 编写自定义的PrintPage事件处理代码

PrintPageEventArgs 参数提供了一系列的方法和属性来控制打印页面。以下是一个更复杂的 PrintPage 事件处理示例,它包括了字体大小、颜色和背景的自定义。

private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
    // 定义页面的宽度和高度
    float pageWidth = e.MarginBounds.Width;
    float pageHeight = e.MarginBounds.Height;

    // 设置字体和颜色
    Font printFont = new Font("Times New Roman", 10, FontStyle.Bold);
    Brush printBrush = new SolidBrush(Color.Black);

    // 设置打印文本
    string textToPrint = "这是自定义的打印内容。";
    e.Graphics.DrawString(textToPrint, printFont, printBrush, new PointF(20, 20));

    // 可以继续添加更多绘制内容...
}

通过以上代码,我们演示了如何在打印页上绘制文本,并且设置了字体样式、大小和颜色。还可以在页面上添加图片、图形和其他元素,为最终用户提供更加丰富的打印体验。重要的是,开发者可以控制页面上所有元素的精确位置和样式,这在打印复杂文档时显得尤为重要。

通过本章节的介绍,我们详细阐述了如何使用 PrintDocument 类进行打印任务的初始化和打印参数的设置,同时展示了如何通过 PrintPage 事件来实现打印页面内容的自定义。这些知识将为实现高质量的打印功能奠定基础。

6. 用户界面设计与打印机检测

6.1 用户界面设计基础(Windows Forms)

6.1.1 窗体设计要点与界面布局

在创建一个用户友好的应用程序时,窗体设计是至关重要的一环。界面布局应该遵循简洁、直观和高效的原则。通过Visual Studio等集成开发环境(IDE),开发者可以利用拖放的方式来创建窗体,并将各种控件放置在合适的位置。

在设计窗体时,需要考虑以下要点:

  • 布局平衡 :确保窗体上的元素分布均匀,避免拥挤或过于空旷的区域。
  • 对齐与边距 :控件应该相互对齐,并且保持一定的边距,以便用户易于点击和识别。
  • 视觉层次 :通过控件的大小、颜色和字体等视觉元素,突出显示更重要的元素,如按钮和文本框。
  • 分组与间隔 :相似或相关的控件应该分组,通过间隔来区分不同的组,使得界面更加清晰。

在C# Windows Forms应用程序中,窗体布局可以通过使用不同的布局管理器来实现,例如 TableLayoutPanel FlowLayoutPanel 。使用这些布局管理器可以保证窗体在不同的屏幕分辨率和窗体大小下均能保持良好的布局。

6.1.2 与用户交互的控件应用

C# Windows Forms提供了多种控件来与用户进行交互。为了使程序更加友好和易于操作,开发者需要熟悉这些控件的使用方法。以下是一些基础控件的介绍:

  • 按钮(Button) :用于执行单一的操作,如开始打印任务。
  • 文本框(TextBox) :用于接收用户输入的文本信息。
  • 下拉列表(ComboBox) :允许用户从预定义的选项中选择一个。
  • 列表框(ListBox) :显示多个选项,用户可以从中选择一个或多个选项。
  • 标签(Label) :用于显示说明性的文本信息,不接受用户输入。

使用控件时,可以设置其属性(如颜色、字体和大小)来提高用户界面的可读性和吸引力。事件处理是与用户进行交互的关键。例如,可以为按钮编写点击事件处理代码,当用户点击按钮时执行特定操作。

6.2 打印机检测与选择

在实现打印功能时,应用程序可能需要支持多台打印机,并允许用户根据需要选择合适的设备。

6.2.1 检测系统可用打印机

在.NET框架中,可以通过 System.Drawing.Printing.PrinterSettings.InstalledPrinters 属性获取系统中已安装的打印机列表。以下是一个简单的示例代码,展示了如何列出所有可用的打印机:

using System;
using System.Drawing.Printing;
using System.Windows.Forms;

public class PrinterLister
{
    public static void ListAllPrinters()
    {
        foreach (var printer in PrinterSettings.InstalledPrinters)
        {
            Console.WriteLine(printer);
        }
    }
}

此代码遍历所有已安装的打印机并将它们打印到控制台。

6.2.2 用户选择打印机的实现方法

用户选择打印机可以通过简单的下拉列表控件实现。用户从列表中选择一个打印机,然后程序根据选定的打印机进行打印设置。这可以通过修改 PrintDocument PrinterSettings 属性来完成。

以下是一个设置打印机的示例代码片段:

using System.Drawing.Printing;

// 假设printerName是用户从下拉列表中选择的打印机名称
string printerName = "选定的打印机名称";
PrintDocument printDocument = new PrintDocument();
printDocument.PrinterSettings.PrinterName = printerName;

这里,我们将用户选择的打印机名称赋值给 PrintDocument 对象的 PrinterSettings.PrinterName 属性,这样程序就会使用指定的打印机来打印文档。如果用户没有选择任何打印机,则默认使用系统设置的默认打印机。

7. 错误处理和程序优化

7.1 错误处理机制

7.1.1 异常捕获与处理策略

异常处理是任何软件开发中的关键部分,它确保应用程序在遇到未预料到的情况时可以优雅地处理错误,防止程序崩溃。在C#中,异常处理通常通过try-catch块来实现。请看以下示例代码:

try
{
    // 尝试执行可能引发异常的代码
    StreamReader reader = new StreamReader("nonexistentfile.txt");
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }
    reader.Close();
}
catch (FileNotFoundException e)
{
    // 捕获特定异常并进行处理
    Console.WriteLine("文件未找到:" + e.Message);
}
catch (Exception e)
{
    // 捕获所有其他异常
    Console.WriteLine("发生错误:" + e.Message);
}

以上代码段尝试打开一个不存在的文件,并使用 StreamReader 读取其内容。 FileNotFoundException 异常被特定捕获,而其他所有异常则被一般性的 Exception 捕获块处理。

7.1.2 常见打印错误的预防与解决

在打印程序中,常见的错误类型包括文件读取错误、打印设置错误以及打印机状态异常。预防这些错误的方法包括:

  • 确保在读取文件之前文件确实存在。
  • 在尝试打印之前检查打印机是否在线和可用。
  • 在执行打印操作前预览文档确保格式正确无误。

例如,以下代码段展示了如何在尝试打印前检查打印机是否可用:

using System.Drawing.Printing;

public bool IsPrinterAvailable(string printerName)
{
    PrintQueue pq;
    try
    {
        pq = new PrintQueue(new PrinterName(printerName));
    }
    catch (ArgumentException)
    {
        // 打印机名称无效
        return false;
    }
    catch (PrintQueueException)
    {
        // 打印队列有问题
        return false;
    }
    return true;
}

这段代码尝试创建一个打印机队列,如果遇到任何问题(例如打印机不存在或无法连接),相应的异常将被捕获并返回 false 表示打印机不可用。

7.2 程序优化与用户体验提升

7.2.1 性能优化的实践技巧

在C#程序中,性能优化可以采取多种方法,比如:

  • 使用异步编程来避免UI阻塞。
  • 优化循环和递归算法,减少不必要的计算。
  • 使用缓存来存储重复计算的结果。

例如,在涉及文件操作和打印时,可以异步读取文件内容,如下代码示例:

public async Task<string> ReadFileAsync(string path)
{
    using (StreamReader reader = new StreamReader(path))
    {
        return await reader.ReadToEndAsync();
    }
}

ReadFileAsync 函数允许文件读取操作异步执行,从而避免UI线程阻塞,提升用户体验。

7.2.2 用户体验改进的建议与方法

用户体验优化往往关注于减少用户操作的复杂度、提升界面直观性和响应速度。以下是几点建议:

  • 界面上提供清晰的指示和反馈。
  • 实施拖放功能以简化文件载入过程。
  • 在文档打印预览期间允许用户进行微调和编辑。

下面的代码段展示了如何为文件载入过程添加进度条,以增强用户反馈:

// 假设有一个进度条控件 named progressBar
public void StartFileLoadingProcess(string filePath)
{
    int totalBytes = new FileInfo(filePath).Length;
    int bytesLoaded = 0;
    // 模拟文件读取过程
    while (bytesLoaded < totalBytes)
    {
        // 假设每步读取固定字节数
        int step = 1024;
        bytesLoaded += step;
        progressBar.Maximum = totalBytes;
        progressBar.Value = bytesLoaded;
        // 模拟耗时操作
        Thread.Sleep(100);
    }
}

这段代码演示了如何在读取文件时更新进度条,告知用户文件载入的进度。通过以上方式,程序不仅在功能上实现需求,同时在用户体验方面也得到了提升。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:C#编程中,载入并打印文本文件是一个常用功能。本实例演示了如何使用 System.IO System.Drawing.Printing 命名空间下的类来实现这一功能。首先,通过 StreamReader 类读取TXT文件内容;其次,利用 PrintDocument 类及其事件处理器 PrintPage 来实现打印逻辑;最后,通过Windows Forms应用程序提供用户界面,让用户选择文件并触发打印。此外,还需确保系统中安装有打印机,并进行错误处理和用户界面优化。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值