C# 中的 Stream

一、揭开 Stream 的神秘面纱

在 C# 的编程世界里,Stream 如同一条隐藏在程序深处的神秘河流,默默地承载着数据的流动。当我们读取文件中的文字、接收网络传来的信息,或是在内存中处理数据块时,Stream 都在幕后发挥着关键作用,它就像是连接数据源头与目的地的无形管道,确保数据的有序传输。

Stream 是一种表示基于流的输入输出的抽象基类,它为 C# 中所有流相关操作提供了基础框架。在这个框架下,无论是文件、内存中的数据块,还是网络数据,都能以连续的方式被读取或写入。这就好比我们通过水管输水,水在水管中持续流动,而 Stream 对于数据来说,就是那根保证数据平稳、持续流动的 “水管”。

二、Stream 的基本概念

(一)Stream 是什么

在 C# 的庞大类库体系中,Stream 是一个抽象基类,它为基于流的输入输出操作构建了一个通用模型。这意味着它定义了一系列的方法和属性,为读取、写入和管理数据流提供了基本框架,但不能被直接实例化 。就像建筑师设计了一座建筑的蓝图,而具体的建筑(如 FileStream、MemoryStream、NetworkStream 等子类)需要依据这张蓝图来构建。

这些子类继承了 Stream 的特性,并针对不同的数据来源和目标进行了具体化实现。例如,FileStream 专门用于文件的读写操作,它能够直接与磁盘上的文件进行交互,将文件视为字节流进行处理;MemoryStream 则专注于内存中的数据操作,允许在内存中创建和操作数据流,适用于临时存储和处理数据的场景;NetworkStream 用于网络数据的传输,在客户端和服务器之间建立起数据传输的通道。

(二)Stream 的主要特点

Stream 的显著特点之一是顺序性。数据在 Stream 中如同水流一般,按照先后顺序依次流动,我们只能按照这种顺序对数据进行读取和写入操作,无法像在数组中那样随机访问数据。这一特性保证了数据处理的有序性,特别适用于处理大量连续的数据。

Stream 的连续性也非常重要。它使得数据可以以连续的方式进行处理,而不需要一次性将所有数据加载到内存中。在处理大文件时,我们可以通过 Stream 逐块读取数据,而不是将整个大文件全部读入内存,这样极大地减少了内存的占用,提高了程序的性能和稳定性。这种连续性还体现在数据的写入过程中,数据能够持续地写入到目标位置,保证数据的完整性。

三、Stream 的常见操作

(一)打开流

在 C# 中,打开流的方式因流的类型而异 。以最常用的文件流 FileStream 为例,我们通过其构造函数来指定文件路径、打开模式以及访问权限等参数。

当我们想要读取一个已存在的文件时,可以这样写:

using System.IO;
FileStream fileStreamRead = new FileStream("example.txt", FileMode.Open, FileAccess.Read);

这段代码中,“example.txt” 是文件的路径,FileMode.Open 表示以打开现有文件的模式进行操作,如果文件不存在则会抛出异常;FileAccess.Read 指定了我们对该文件只有读取的权限。

若要创建一个新文件并准备写入数据,代码如下:

FileStream fileStreamWrite = new FileStream("newFile.txt", FileMode.Create, FileAccess.Write);

这里 FileMode.Create 表示如果文件不存在则创建新文件,如果文件已存在则覆盖原有内容;FileAccess.Write 赋予了对文件的写入权限。

对于内存流 MemoryStream,由于它是在内存中操作数据流,不需要指定外部文件路径,直接实例化即可:

MemoryStream memoryStream = new MemoryStream();

这种方式创建的内存流初始为空,可以随时向其中写入数据或从中读取数据。

(二)读取数据

从流中读取数据是 Stream 的核心操作之一,以 FileStream 读取文件内容为例,我们可以使用 Read 方法来实现。该方法会将流中的数据读取到一个字节数组中,并返回实际读取的字节数。

using System.IO;
using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        string content = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.Write(content);
    }
}

在这段代码中,我们首先创建了一个大小为 1024 字节的缓冲区 buffer ,用于存储从文件流中读取的数据。在 while 循环中,每次调用 Read 方法尝试从文件流中读取最多 1024 字节的数据到 buffer 中,返回的 bytesRead 表示实际读取到的字节数。当 bytesRead 为 0 时,表示已经到达文件末尾,循环结束。每次读取到数据后,我们使用 UTF - 8 编码将字节数组转换为字符串并输出到控制台。

(三)写入数据

将数据写入流同样通过 Stream 的 Write 方法来实现。以向文件中写入数据为例,以下是使用 FileStream 和 StreamWriter 的示例代码:

using System.IO;
string contentToWrite = "Hello, Stream!";
using (FileStream fileStream = new FileStream("output.txt", FileMode.Create, FileAccess.Write))
using (StreamWriter streamWriter = new StreamWriter(fileStream))
{
    streamWriter.Write(contentToWrite);
}

在这段代码中,我们首先创建了一个 FileStream 对象,以创建模式打开名为 “output.txt” 的文件,并赋予写入权限。然后,我们创建了一个 StreamWriter 对象,将其与 FileStream 对象关联起来。最后,通过 StreamWriter 的 Write 方法将字符串 “Hello, Stream!” 写入到文件中。在使用完 StreamWriter 和 FileStream 后,由于我们使用了 using 语句,它们会自动被正确关闭和释放资源。

(四)关闭流

关闭流是非常重要的操作,它能确保资源的正确释放,避免资源泄漏和潜在的错误。在 C# 中,我们强烈推荐使用 using 语句来管理流对象的生命周期。

using System.IO;
using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
{
    // 在这里进行文件读取操作
    byte[] buffer = new byte[1024];
    int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
}
// 当离开using语句块时,fileStream会自动调用Dispose方法关闭流

在上述代码中,当程序执行到 using 语句块结束时,无论在块内是否发生异常,文件流 fileStream 都会自动调用其 Dispose 方法,从而关闭流并释放与之关联的所有资源。如果不使用 using 语句,我们则需要手动调用 Close 方法或 Dispose 方法来关闭流,例如:

FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read);
try
{
    byte[] buffer = new byte[1024];
    int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
}
finally
{
    fileStream.Close();
}

在这个示例中,我们在 try - finally 块中进行文件读取操作,并在 finally 块中调用 Close 方法关闭文件流。这样可以确保无论读取过程中是否发生异常,文件流都能被正确关闭。但相比之下,using 语句的方式更加简洁明了,且能有效避免因代码逻辑复杂而遗漏关闭流的情况。

四、Stream 的常用类型

(一)FileStream

FileStream 就像是连接程序与磁盘文件的桥梁,专门用于文件的读写操作。它允许我们以字节为单位,对文件进行随机访问和顺序访问。在处理大文件时,FileStream 的优势尤为明显,它可以通过设置缓冲区大小,减少磁盘 I/O 操作的次数,从而提高读写效率。例如,当我们需要读取一个大型的视频文件时,使用 FileStream 能够逐块读取数据,避免一次性将整个大文件加载到内存中,有效降低内存占用。

在构造 FileStream 对象时,我们需要指定文件路径、打开模式、访问权限等参数。以读取文件为例,代码如下:

using System.IO;
FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read);

这段代码中,“example.txt” 是要读取的文件路径,FileMode.Open 表示以打开现有文件的模式进行操作,FileAccess.Read 则指定了对该文件的读取权限。通过这种方式,我们就可以使用 FileStream 对象对文件进行后续的读取操作。

(二)MemoryStream

MemoryStream 如同一个在内存中开辟的临时数据存储空间,主要用于在内存中处理数据流。与 FileStream 不同,它不需要与外部文件进行交互,数据的读写都在内存中完成。这使得 MemoryStream 在处理一些临时数据或需要频繁进行数据操作的场景中表现出色。例如,在进行数据加密和解密的过程中,我们可以将待处理的数据先存储在 MemoryStream 中,方便进行加密算法的运算,而无需频繁地读写磁盘文件,大大提高了处理速度。

使用 MemoryStream 非常方便,以下是一个简单的示例,展示了如何在 MemoryStream 中写入和读取数据:

using System.IO;
using System.Text;
MemoryStream memoryStream = new MemoryStream();
string data = "Hello, MemoryStream!";
byte[] buffer = Encoding.UTF8.GetBytes(data);
memoryStream.Write(buffer, 0, buffer.Length);
memoryStream.Position = 0;
byte[] readBuffer = new byte[buffer.Length];
int bytesRead = memoryStream.Read(readBuffer, 0, readBuffer.Length);
string result = Encoding.UTF8.GetString(readBuffer, 0, bytesRead);
Console.WriteLine(result);

在这段代码中,我们首先创建了一个 MemoryStream 对象。然后,将字符串数据转换为字节数组,并写入到 MemoryStream 中。通过设置 Position 属性为 0,将流的位置重置到起始位置,以便进行后续的读取操作。最后,从 MemoryStream 中读取数据,并将其转换回字符串进行输出。

(三)BufferedStream

BufferedStream 为数据的读写提供了缓冲机制,它就像是在数据传输的路径上设置了一个临时仓库。当我们从流中读取数据时,BufferedStream 会一次性从底层流中读取多个字节的数据,并存储在缓冲区中。当我们再次读取数据时,如果缓冲区中有数据,就直接从缓冲区中读取,而不需要频繁地访问底层数据源,从而提高了读取效率。同样,在写入数据时,BufferedStream 会先将数据写入缓冲区,当缓冲区满了或者调用 Flush 方法时,才会将缓冲区中的数据一次性写入到底层流中,减少了对底层设备的写入次数。

下面是一个使用 BufferedStream 提高文件读取效率的示例:

using System.IO;
using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
using (BufferedStream bufferedStream = new BufferedStream(fileStream))
{
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = bufferedStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        // 处理读取到的数据
    }
}

在这个例子中,我们首先创建了一个 FileStream 对象来打开文件,然后将 FileStream 对象传递给 BufferedStream 的构造函数,创建了一个 BufferedStream 对象。通过 BufferedStream 的 Read 方法读取数据时,实际上是从缓冲区中读取数据,而不是直接从文件中读取,从而提高了读取效率。

(四)NetworkStream

NetworkStream 在网络通信领域发挥着关键作用,它实现了在网络上进行数据传输的功能。在客户端和服务器之间建立网络连接后,NetworkStream 就成为了数据传输的通道。无论是在开发网络应用程序,如即时通讯软件、文件传输工具,还是进行网络服务的开发,NetworkStream 都不可或缺。例如,在一个简单的聊天程序中,客户端和服务器之间通过 NetworkStream 进行消息的发送和接收,确保聊天信息能够实时、准确地在双方之间传递。

在使用 NetworkStream 时,通常需要与 TcpClient、TcpListener 等类配合使用。以下是一个简单的客户端和服务器之间通过 NetworkStream 进行数据传输的示例:

服务器端代码
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
class Server
{
    static void Main()
    {
        TcpListener listener = new TcpListener(1234);
        listener.Start();
        Console.WriteLine("服务器启动,等待客户端连接...");
        TcpClient client = listener.AcceptTcpClient();
        Console.WriteLine("客户端已连接。");
        NetworkStream stream = client.GetStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = stream.Read(buffer, 0, buffer.Length))!= 0)
        {
            string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
            Console.WriteLine("收到客户端发送的数据: " + receivedData);
        }
        client.Close();
        listener.Stop();
        Console.WriteLine("服务器已关闭。");
    }
}
客户端代码
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
class Client
{
    static void Main()
    {
        TcpClient client = new TcpClient("localhost", 1234);
        Console.WriteLine("客户端启动,正在连接服务器...");
        NetworkStream stream = client.GetStream();
        string message = "Hello, Server!";
        byte[] data = Encoding.UTF8.GetBytes(message);
        stream.Write(data, 0, data.Length);
        Console.WriteLine("已发送消息: " + message);
        client.Close();
        Console.WriteLine("客户端已关闭。");
    }
}

在这个示例中,服务器端通过 TcpListener 监听指定端口,当有客户端连接时,获取与客户端的连接并创建 NetworkStream 对象,通过该对象读取客户端发送的数据。客户端则通过 TcpClient 连接到服务器,创建 NetworkStream 对象后,将数据写入到流中发送给服务器。通过这种方式,实现了客户端和服务器之间的数据传输。

五、Stream 的实际应用场景

(一)文件读写操作

在文件读取操作中,Stream 可谓是 “主力军”。当我们需要从硬盘上读取一个文本文件时,FileStream 配合 StreamReader 能轻松完成任务。例如,在读取一篇小说文档时,代码如下:

using System.IO;
using (FileStream fileStream = new FileStream("novel.txt", FileMode.Open, FileAccess.Read))
using (StreamReader streamReader = new StreamReader(fileStream))
{
    string content = streamReader.ReadToEnd();
    Console.WriteLine(content);
}

这段代码首先通过 FileStream 以只读模式打开名为 “novel.txt” 的文件,然后将 FileStream 传递给 StreamReader,利用 StreamReader 的 ReadToEnd 方法将整个文件内容读取为一个字符串并输出到控制台。

在文件写入操作中,Stream 同样表现出色。假设我们要记录系统运行过程中的日志信息,就可以使用 FileStream 和 StreamWriter 来实现。以下是一个简单的日志写入示例:

using System.IO;
string logMessage = "系统在[具体时间]发生了[具体事件]";
using (FileStream fileStream = new FileStream("log.txt", FileMode.Append, FileAccess.Write))
using (StreamWriter streamWriter = new StreamWriter(fileStream))
{
    streamWriter.WriteLine(logMessage);
}

在这个例子中,FileStream 以追加模式打开 “log.txt” 文件,这样新的日志信息会被添加到文件末尾,而不会覆盖原有内容。StreamWriter 则负责将日志消息写入文件中。

在文件追加操作中,Stream 的优势也十分明显。比如我们在一个不断更新的文本文件中追加新的内容,以记录用户的操作记录。示例代码如下:

using System.IO;
string userAction = "用户[用户名]在[具体时间]进行了[具体操作]";
using (FileStream fileStream = new FileStream("userActions.txt", FileMode.Append, FileAccess.Write))
using (StreamWriter streamWriter = new StreamWriter(fileStream))
{
    streamWriter.WriteLine(userAction);
}

通过这种方式,每次用户进行操作时,对应的操作记录都会被追加到 “userActions.txt” 文件中,方便后续查看和分析。

(二)网络数据传输

在网络数据传输领域,Stream 是实现数据交换的关键桥梁。以常见的 HTTP 协议为例,当客户端向服务器发送请求时,请求数据会通过 NetworkStream 传输到服务器端;服务器处理完请求后,响应数据又通过 NetworkStream 返回给客户端。例如,在一个简单的网页爬虫程序中,我们需要从指定的网页获取数据,代码如下:

using System;
using System.IO;
using System.Net;
using System.Text;
class WebCrawler
{
    static void Main()
    {
        string url = "https://example.com";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (Stream stream = response.GetResponseStream())
        using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8))
        {
            string htmlContent = streamReader.ReadToEnd();
            Console.WriteLine(htmlContent);
        }
        response.Close();
    }
}

在这段代码中,首先创建一个 HttpWebRequest 对象,用于向指定的 URL 发送请求。获取到响应后,通过 response.GetResponseStream () 方法获取到响应流,再使用 StreamReader 将流中的数据读取为字符串,从而得到网页的 HTML 内容。

在 FTP 协议中,Stream 同样发挥着重要作用。当我们需要从 FTP 服务器上传或下载文件时,就会用到 Stream。以下是一个简单的从 FTP 服务器下载文件的示例:

using System;
using System.IO;
using System.Net;
class FtpDownloader
{
    static void Main()
    {
        string ftpUrl = "ftp://ftp.example.com/file.txt";
        string username = "user";
        string password = "pass";
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
        request.Credentials = new NetworkCredential(username, password);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        using (Stream responseStream = response.GetResponseStream())
        using (FileStream fileStream = new FileStream("localFile.txt", FileMode.Create))
        {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                fileStream.Write(buffer, 0, bytesRead);
            }
        }
    }
}

在这个例子中,我们创建一个 FtpWebRequest 对象,设置好 FTP 服务器的地址、用户名、密码以及请求方法(下载文件)。获取到响应后,从响应中获取到流,再将流中的数据读取到本地文件中,完成文件的下载操作。

(三)内存数据处理

在内存数据处理方面,MemoryStream 是一个非常实用的工具。例如,在进行数据加密和解密的过程中,我们可以先将需要处理的数据存储在 MemoryStream 中,方便进行加密算法的运算。假设我们有一个简单的数据加密需求,将一段字符串进行加密处理后存储在内存中,代码如下:

using System.IO;
using System.Text;
class DataEncryption
{
    static void Main()
    {
        string originalData = "敏感信息";
        byte[] dataBytes = Encoding.UTF8.GetBytes(originalData);
        using (MemoryStream memoryStream = new MemoryStream())
        {
            memoryStream.Write(dataBytes, 0, dataBytes.Length);
            memoryStream.Position = 0;
            // 这里可以进行加密算法的操作,例如简单的异或加密
            byte[] encryptedData = new byte[dataBytes.Length];
            for (int i = 0; i < dataBytes.Length; i++)
            {
                encryptedData[i] = (byte)(dataBytes[i] ^ 0x1F);
            }
            memoryStream.Write(encryptedData, 0, encryptedData.Length);
            memoryStream.Position = 0;
            byte[] readData = new byte[memoryStream.Length];
            memoryStream.Read(readData, 0, readData.Length);
            string result = Encoding.UTF8.GetString(readData);
            Console.WriteLine(result);
        }
    }
}

在这段代码中,首先将原始字符串转换为字节数组,并写入到 MemoryStream 中。然后在内存流中对数据进行简单的异或加密操作,将加密后的数据再次写入内存流。最后从内存流中读取数据,并转换回字符串进行输出。

在数据转换场景中,MemoryStream 也能大显身手。比如将一个图像文件读取到内存中,进行格式转换后再进行存储或传输。以下是一个简单的将 Bitmap 图像转换为字节数组并存储在 MemoryStream 中的示例:

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
class ImageConverter
{
    static void Main()
    {
        using (Bitmap bitmap = new Bitmap("image.jpg"))
        using (MemoryStream memoryStream = new MemoryStream())
        {
            bitmap.Save(memoryStream, ImageFormat.Png);
            byte[] imageBytes = memoryStream.ToArray();
            // 这里可以对imageBytes进行进一步的操作,如传输到网络等
        }
    }
}

在这个例子中,我们使用 Bitmap 类读取一个 JPEG 格式的图像文件,然后将其以 PNG 格式保存到 MemoryStream 中,最后通过 ToArray 方法将内存流中的数据转换为字节数组,方便后续的处理和传输。

六、总结与展望

通过对 C# 中 Stream 的深入探秘,我们像是揭开了数据处理领域的一层神秘面纱,领略到了它在数据传输与处理方面的强大魅力。从 Stream 的基本概念出发,了解到它作为抽象基类为各种数据输入输出操作提供了统一框架,再到深入学习其常见操作,包括打开、读取、写入和关闭流,以及熟悉 FileStream、MemoryStream、BufferedStream、NetworkStream 等常用类型及其在不同场景下的应用,我们逐步掌握了 Stream 这一强大工具的使用方法。

展望未来在实际编程中的应用,Stream 将为我们的开发工作带来诸多便利和效率提升。在文件处理方面,无论是日常的文本文件读写,还是处理大型二进制文件,Stream 都能以其高效的方式,确保数据的准确读写,为各类应用程序提供坚实的数据基础。在网络通信领域,随着互联网应用的不断发展,数据传输的需求日益增长,Stream 作为网络数据传输的核心,将在构建稳定、高效的网络连接和数据交互中发挥关键作用。在内存数据处理场景中,MemoryStream 等工具能够帮助我们更灵活地操作和管理内存中的数据,为数据的临时存储、加密解密、格式转换等操作提供便捷的解决方案。

总之,对 Stream 的深入理解和熟练运用,将使我们在 C# 编程的道路上如虎添翼,能够更加高效地开发出高质量、高性能的应用程序,以应对不断变化的编程需求和挑战。希望各位开发者能够在实际项目中积极运用 Stream,挖掘其更多的潜力,创造出更加优秀的软件作品 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/954649.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一些常见的Java面试题及其答案

Java基础 1. Java中的基本数据类型有哪些&#xff1f; 答案&#xff1a;Java中的基本数据类型包括整数类型&#xff08;byte、short、int、long&#xff09;、浮点类型&#xff08;float、double&#xff09;、字符类型&#xff08;char&#xff09;和布尔类型&#xff08;boo…

PyTorch框架——基于深度学习YOLOv5神经网络水果蔬菜检测识别系统

基于深度学习YOLOv5神经网络水果蔬菜检测识别系统&#xff0c;其能识别的水果蔬菜有15种&#xff0c;# 水果的种类 names: [黑葡萄, 绿葡萄, 樱桃, 西瓜, 龙眼, 香蕉, 芒果, 菠萝, 柚子, 草莓, 苹果, 柑橘, 火龙果, 梨子, 花生, 黄瓜, 土豆, 大蒜, 茄子, 白萝卜, 辣椒, 胡萝卜,…

用css和html制作太极图

目录 css相关参数介绍 边距 边框 伪元素选择器 太极图案例实现、 代码 效果 css相关参数介绍 边距 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}div{width: …

WPF、控件模板(ControlTemplate)和数据模板(DataTemplate)

前言 在 WPF 中&#xff0c;控件种类丰富且功能非常完善。一个显著的优点是 WPF 提供了强大的自定义能力和灵活的用户界面表现&#xff0c;能够满足各种复杂的应用需求。其中&#xff0c;ControlTemplate 和 DataTemplate 是两个非常重要的概念&#xff0c;分别用于自定义控件…

RAG实战_01代码生成_02智能检索

整理了RAG案例的Git代码 https://github.com/LGRY/RAG_Tutorial/tree/main 【注意事项】 01 代码生成系统源代码中使用的weaviate向量数据库&#xff0c;不支持window系统&#xff0c;建议换系统/换向量数据库02 智能检索系统 同样需要配置向量数据库&#xff0c;可以先安…

【Linux系统编程】—— 自动化构建工具Makefile指南

文章目录 背景基本使用推导过程适度扩展语法 背景 Makefile 是衡量开发者是否具备完成大型工程能力的一个重要标志。在一个工程中&#xff0c;源文件的数量可能极多&#xff0c;这些文件会按照类型、功能或模块分布在多个目录中。Makefile 通过定义一系列规则&#xff0c;指定…

【JavaWeb01】JavaWeb开发基础:HTML的深度解析与应用

文章目录 前言&#x1f30d;一.B/S 软件开发架构简述&#x1f30d;二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 &#x1f30d;三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…

Android-目前最稳定和高效的UI适配方案

谈到适配&#xff0c;首先需要介绍几个基本单位&#xff1a; 1、密度无关像素&#xff08;dp&#xff09;&#xff1a; 含义&#xff1a;density-independent pixel&#xff0c;叫dp或dip&#xff0c;与终端上的实际物理像素点无关 单位&#xff1a;dp&#xff0c;可以保证在…

图片和短信验证码(头条项目-06)

1 图形验证码接口设计 将后端⽣成的图⽚验证码存储在redis数据库2号库。 结构&#xff1a; {img_uuid:0594} 1.1 创建验证码⼦应⽤ $ cd apps $ python ../../manage.py startapp verifications # 注册新应⽤ INSTALLED_APPS [django.contrib.admin,django.contrib.auth,…

java8 springboot 集成javaFx 实现一个客户端程序

1. 先创建一个springboot 程序(此步骤不做流程展示) 2. 更改springboot的版本依赖和导入所需依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.7</versio…

linux手动安装mysql5.7

一、下载mysql5.7 1、可以去官方网站下载mysql-5.7.24-linux-glibc2.12-x86_64.tar压缩包&#xff1a; https://downloads.mysql.com/archives/community/ 2、在线下载&#xff0c;使用wget命令&#xff0c;直接从官网下载到linux服务器上 wget https://downloads.mysql.co…

数据结构(链表 哈希表)

在Python中&#xff0c;链表和哈希表都是常见的数据结构&#xff0c;可以用来存储和处理数据。 链表是一种线性数据结构&#xff0c;由一系列节点组成&#xff0c;每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以用来实现栈、队列以及其他数据结构。Python中可…

【GPT进化之路】从 GPT-1 的初试锋芒到 GPT-4 的跨模态智能时代

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

linux之进程信号(初识信号,信号的产生)

目录 引入一、初识信号(信号预备知识)1.生活中的信号2.Linux中的信号3.信号进程得出的初步结论 二、信号的产生1.通过终端输入产生信号拓展: 硬件中断2.调用系统函数向进程发信号3.硬件异常产生信号4.软件条件产生信号拓展: 核心转储技术总结一下&#xff1a; 引入 一、初识信…

24-25-1-单片机开卷部分习题和评分标准

依据相关规定试卷必须按评分标准进行批改。 给分一定是宽松的&#xff0c;能给分一定给&#xff0c;如有疑问也可以向学院教务办申请查卷。 一部分学生期末成绩由于紧张或其他原因导致分数过低&#xff0c;也是非常非常遗憾的。 个人也是非常抱歉的。 开卷考试 简答题 第一…

电动汽车V2G技术Matlab/Simulink仿真模型

今天给大家更新关于V2G技术的仿真&#xff0c;不是研究这个方向的&#xff0c;可能会对这个名称比较陌生&#xff0c;那么&#xff0c;什么是“V2G”&#xff1f; V2G全称&#xff1a;Vehicle-to-Grid&#xff0c;即车网互动&#xff0c;利用电动汽车特有的储能功能与电网“双…

统计学习算法——决策树

内容来自B站Up主&#xff1a;风中摇曳的小萝卜https://www.bilibili.com/video/BV1ar4y137GD&#xff0c;仅为个人学习所用。 问题引入 有15位客户向某银行申请贷款&#xff0c;下面是他们的一些基本信息&#xff0c;类别列表示是否通过贷款申请&#xff0c;是表示通过贷款申…

Pytorch导出onnx模型并在C++环境中调用(含python和C++工程)

Pytorch导出onnx模型并在C环境中调用&#xff08;含python和C工程&#xff09; 工程下载链接&#xff1a;Pytorch导出onnx模型并在C环境中调用&#xff08;python和C工程&#xff09; 机器学习多层感知机MLP的Pytorch实现-以表格数据为例-含数据集和PyCharm工程中简单介绍了在…

Uniapp判断设备是安卓还是 iOS,并调用不同的方法

在 UniApp 中&#xff0c;可以通过 uni.getSystemInfoSync() 方法来获取设备信息&#xff0c;然后根据系统类型判断当前设备是安卓还是 iOS&#xff0c;并调用不同的方法。 示例代码 export default {onLoad() {this.checkPlatform();},methods: {checkPlatform() {// 获取系…

VMWare虚拟机+Ubuntu24.04+ROS2Jazzy版本安装——踩坑及爬坑过程

VMWare安装 VMWare安装参考VMWare安装&#xff0c;WMWare workstation从17版本以后就面向个人用户免费开放了&#xff0c;所以在安装的最后只要勾选“用于个人”这个选项&#xff0c;就无需再输入激活码等&#xff0c;非常方便。 WMWare workstation17的获取地址&#xff1a;通…