Linux应用开发基础知识——字符文字编码(五)

前言:

TXT 文件中保存的是字符的核心:它的编码值。而 Notepad 上显示时, 这些字符对应什么样的形状态,这是由字符文件决定的。编码值,字体是两个不一样的东西,比如 A 的编码值是 0x41,但是在屏幕上显示出来时可以使用不同的形状。

什么叫编码?就是一个字符用什么数字来表示。在计算机里一切都是用数字来表示,比如字符 A,用 0x01 还是 0x02 来表示它?我们使用 0x41 来表示它。 当你去打开一个 TXT 文件时,发现里面含有数值 0x41,你就知道了:哦,这里有一个字符 A。

下面让我们一起学习一下文字的编码方式吧

目录

一、字符的编码方式

1.编码与字体

(1)ASCII

(2)ANSI

(3)UNICODE

[2.UNICODE 编码实现](#2.UNICODE 编码实现)

[(1)使用 3 个字节表示一个 UNICODE](#(1)使用 3 个字节表示一个 UNICODE)

[(2)UCS-2 Little endian/UTF-16 LE](#(2)UCS-2 Little endian/UTF-16 LE)

[(3)UCS-2 Big endian/UTF-16 BE](#(3)UCS-2 Big endian/UTF-16 BE)

(4)UTF8

[二、ASCII 字符的点阵显示](#二、ASCII 字符的点阵显示)

1.获取点阵

2.描点

[3.main 函数](#3.main 函数)

[4.编译 c 文件 show_ascii.c](#4.编译 c 文件 show_ascii.c)

5.上机实验:

三、中文字符的点阵显示

1.编码格式

(1)默认编码:

(2)指定编码格式

[1)GB2312 转为 UTF-8](#1)GB2312 转为 UTF-8)

[2)UTF-8 转为 GB2312](#2)UTF-8 转为 GB2312)

2.汉字区位码

(1)打开汉字库文件

(2)编写显示汉字的函数

[(3) 使用 lcd_put_chinese 函数](#(3) 使用 lcd_put_chinese 函数)

四、编译程序与上机测试

1.编译命令:

2.上机实验

[3.实验效果 :](#3.实验效果 :)


一、字符的编码方式

1.编码与字体

(1)ASCII

是"American Standard Code for Information Interchange"的缩 写,美国信息交换标准代码。 电脑毕竟是西方人发明的,他们常用字母就 26 个,区分大小写、加上标点 符号也没超过 127 个,每个字符用一个字节来表示就足够了。一个字节的 7 位就 可以表示 128 个数值,在 ASCII 码中最高位永远是 0。

字符和数值的对应关系可以参考:https://baike.baidu.com/item/ASCII

(2)ANSI

使用记事本保存文件时,可以选择"ANSI"编码,却没有"ASCII",如图

ASNI 是 ASCII 的扩展,向下包含 ASCII。对于 ASCII 字符仍以一个字节来 表示,对于非 ASCII 字符则使用 2 字节来表示。并没有固定的 ASNI 编码,它跟 "本地化"(locale)密切相关。比如在中国大陆地区,ANSI 的默认编码是 GB2312; 在港澳台地区默认编码是 BIG5。

以数值"0xd0d6"为例,对于 GB2312 编码它 表示"中";对于 BIG5 编码它表示"笢"。所以对于 ANSI 编码的 TXT 文件,如 果你打开它发现乱码,那么还得再次细分它的具体编码。

比如对于一个 TXT 文件,里面的数值如下:

使用 Notepad 打开后,选择不同的编码(或称为字符集),有不一样的显示, 如下:

这仅仅是在中国地区就出现这些不兼容的问题。对于不同国家,它们默认的 ANSI 编码各不相同,所以同一个 TXT 文件在不同国家就很有可能出现乱码。

根本的原理在于没有"统一的编码",那解决方法自然就是使用"统一的编码":UNICODE

(3)UNICODE

在 ANSI 标准中,很多种文字都有自己的编码标准,汉字简体字有 GB2312、 繁体字有 BIG5,这难免同一个数值对应不同字符。比如数值"0xd0d6",对于 GB2312 编码它表示"中";对于 BIG5 编码它表示"笢"。这造成了使用 ANSI 编码保存的文件,不适合跨地区交流。

UNICODE 编码就是解决这类问题:对于地球上任意一个字符,都给它一个唯 一的数值。 UNICODE 仍然向下兼容 ASCII,但是对于其他字符会有对应的数值,比如对 于**"中"、"笢"** ,它们的数值分别是:0x4e2d、0x7b22

UNICODE 中的数值范围是 0x0000 至 0x10FFFF,有 1,114,111 即 100 多万 个数值,可以表示 100 多万个字符,足够地球人使用了.

2.UNICODE 编码实现

所谓编码实现,就是对于一个数值,怎么表示它。这很奇怪,数值还能怎么 表示?比如"中"的 UNICODE 值是 0x4e2d,在 TXT 文件中怎么表示 0x4e2d? 直接写入 0x4e2d?不行!

比如在 TXT 文件中写入 2 字节数据"0x2d 0x4e",它可以用来表示"中" 字吗?不能!它们对应 ASCII 字符"-N"。

问题的关键在于:怎么断字。在 TXT 文件中,2 字节数据"0x2d 0x4e"是作为一个整体看待,还是拆成 2 部分看待?

(1)使用 3 个字节表示一个 UNICODE

UNICODE 的最大值是 0x10FFFF,那使用 3 个字节来表示一个 UNICODE 数值?这当然是很省事的方法,但是会造成浪费,比如字符 A 的 UNICOCDE 值是 0x41,难道也用"0x41 0x00 0x00"这 3 个字节来表示?这样会造成很大的内存浪费。

(2)UCS-2 Little endian/UTF-16 LE

每个 UNICODE 值用 3 字节来表示有点浪费,那只用 2 字节呢?它可以表示 2^16=65536 个字符,全世界常用的字符都可以表示了。

Little endian 表示小字节序,数值中权重低的字节放在前面,比如字符 "A 中"在 TXT 文件中的数值如下,其中的"A"使用"0x41 0x00"两字节表 示;"中"使用"0x2d 0x4e"两字节表示。文件开头的"0xff 0xfe"表示"UTF-16 LE"。

(3)UCS-2 Big endian/UTF-16 BE

Big endian 表示大字节序,数值中权重低的字节放在后面,比如字符"ab 中"在 TXT 文件中的数值如下,其中的"A"使用"0x00 0x41"两字节表示; "中"使用"0x4e 0x2d"两字节表示。文件开头的"0xfe 0xff"表示"UTF-16 BE"。

(4)UTF8

在上面 2 种方法中,每一个 UNICODE 使用 2 字节来表示,这有 3 个缺点: 表示的字符数量有限、对于 ASCII 字符有空间浪费、如果文件中有某个字节丢失,这会使得后面所有字符都因为错位而无法显示。

使用 UTF8 可以解决上述所有问题。UTF8 是变长的编码方法,有 2 种 UTF8 格式的文件:带有头部、不带头部。先举例,看图

对于其中的 ASCII 字符,在 UTF8 文件中直接用其 ASCII 码来表示,比如上图中的 0x61 表示字符 a、0x62 表示字符 b。上图中的 3 个字节"0xe4 0xb8 0xad"表示的数值是 0x4e2d,对应"中"的 UNICODE 码 。

对于非 ASCII 字符,使用变长的编码:每一个字节的高位都自带长度信息。

0xe4 的二进制是"11100100",高位有 3 个 1,表示从当前字节起有 3 字节参与表示 UNICODE;

0xb8 的二进制是"10111000",高位有 1 个 1,表示从当前字节起有 1 字节 参与表示 UNICODE;

0xad 的二进制是"10101101",高位有 1 个 1,表示从当前字节起有 1 字节 参与表示 UNICODE;

除去高位的"1110"、"10"、"10"后,剩下的二进制数组合起来得到 "01001110001101",它就是 0x4e2d,即"中"的 UNICODE 值。

使用 UTF8 编码时,即使 TXT 文件中丢失了某些数据,也只会影响到当前字 符的显示,后面的字符不受影响。

二、ASCII 字符的点阵显示

要在 LCD 中显示一个 ASCII 字符,即英文字母这些字符,首先是要找到字 符对应的点阵。在 Linux 内核源码中有这个文件**:lib\fonts\font_8x16.c**, 里面以数组形式保存各个字符的点阵,比如:

数组里的数字是如何表示点阵的?以字符 A 为例

上图左侧有 16 行数值,每行 1 个字节。每一个节对应右侧一行中 8 个像素: 像素从右边数起,bit0 对应第 0 个像素,bit1 对应第 1 个像素,......,bit7 对 应第 7 个像素。某位的值为 1时,表示对应的像素要被点亮;值为 0 时表示对应 的像素要熄灭。

所以要显示某个字符时,根据它的 ASCII 码在 fontdata_8x16 数组中找到 它的点阵,然后取出这 16 个字节去描画 16 行像素。

比如字符 A 的 ASCII 值是 0x41,那么从 fontdata_8x160x41\*16开始取 其点阵数据。

核心函数是 void lcd_put_ascii(int x, int y, unsigned char c), 它在 LCD 的(x,y)位置处显示字符 c,代码如下图所示:

cpp 复制代码
4691 void lcd_put_ascii(int x, int y, unsigned char c)
4692 {
4693     unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
4694     int i, b;
4695     unsigned char byte;
4696
4697     for (i = 0; i < 16; i++)
4698     {
4699         byte = dots[i];
4700         for (b = 7; b >= 0; b--)
4701         {
4702             if (byte & (1<<b))
4703             {
4704                 /* show */
4705                 lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */
4706             }
4707             else
4708             {
4709                 /* hide */
4710                 lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
4711             }
4712         }
4713     }
4714 }

1.获取点阵

对于字符 c,char c,它的点阵获取方法如下:

cpp 复制代码
4693  unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];

2.描点

根据"字符 A 的点阵",我们分析下如何利用点阵在 LCD 上显示一 个英文字母。

因为有十六行,所以首先要有一个循环 16 次的大循环,然后每一行里有 8 位,那么在每一个大循环里也需要一个循环 8 次的小循环。小循环里的判断单行 的描点情况,如果是 1,就填充白色,如果是 0 就填充黑色,如此一来,就可以 显示出黑色底,白色轮廓的英文字母。

cpp 复制代码
4697    for (i = 0; i < 16; i++)
4698     {
4699         byte = dots[i];
4700         for (b = 7; b >= 0; b--)
4701         {
4702             if (byte & (1<<b))
4703             {
4704                 /* show */
4705                 lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */
4706             }
4707             else
4708             {
4709                 /* hide */
4710                 lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
4711             }
4712         }
4713     }

3.main 函数

main 函数中首先要打开 LCD 设备,获取 Framebuffer 参数,实现 lcd_put_pixel 函数;然后调用 lcd_put_ascii 即可绘制字符。

cpp 复制代码
4716 int main(int argc, char **argv)
4717 {
4718     fd_fb = open("/dev/fb0", O_RDWR);
4719     if (fd_fb < 0)
4720     {
4721         printf("can't open /dev/fb0\n");
4722         return -1;
4723     }
4724     if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
4725     {
4726         printf("can't get var\n");
4727         return -1;
4728     }
4729
4730     line_width  = var.xres * var.bits_per_pixel / 8;
4731     pixel_width = var.bits_per_pixel / 8;
4732     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
4733     fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
4734     if (fbmem == (unsigned char *)-1)
4735     {
4736         printf("can't mmap\n");
4737         return -1;
4738     }
4739
4740     /* 清屏: 全部设为黑色 */
4741     memset(fbmem, 0, screen_size);
4742
4743     lcd_put_ascii(var.xres/2, var.yres/2, 'A'); /*在屏幕中间显示8*16的字母A*/
4744
4745     munmap(fbmem , screen_size);
4746     close(fd_fb);
4747
4748     return 0;
4749 }
4750

4.编译 c 文件 show_ascii.c

cpp 复制代码
arm-buildroot-linux-gnueabihf-gcc -o show_ascii show_ascii.c

5.上机实验:

cpp 复制代码
[root@100ask:~]#  mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
[root@100ask:~]#  cp /mnt/show_ascii ./

把 show_ascii 程序放到板子上,执行命令:./show_ascii。如果实验成 功,我们将看到屏幕中间会显示出一个白色的字母'A' ,效果如下:

三、中文字符的点阵显示

1.编码格式

使用点阵字库时,中文字符的显示原理跟 ASCII 字符是一样的。要注意的地 方在于中文的编码:在 C 源文件中它的编码方式是 GB2312 还是 UTF-8?编译出 的可执行程序,其中的汉字编码方式是 GB2312 还是 UTF-8?

**注意:**一般不会使用 UTF-16 的编码方式,在这种方式下 ASCII 字符也是用 2 字节来表示,而其中一个字节是 0,但是在 C 语言中 0 表示字符串的结束符,会引起误会。

编写 C 程序时,可以使用 ANSI 编码,或是 UTF-8 编码;在编译程序时, 可以使用以下的选项告诉编译器:

cpp 复制代码
-finput-charset=GB2312
-finput-charset=UTF-8

如果不指定"-finput-charset",GCC 就会默认 C 程序的编码方式为 UTF-8,即使你是以 ANSI 格式保存,也会被当作 UTF-8 来对待。

对于编译出来的可执行程序,可以指定它里面的字符是以什么方式编码,可 以使用以下的选项编译器:

cpp 复制代码
-fexec-charset=GB2312
-fexec-charset=UTF-8

如果不指定"-fexec-charset",GCC 就会默认编译出的可执行程序中字符 的编码方式为 UTF-8。

如果"-finput-charset"与"-fexec-charset"不一样,编译器会进行 格式转换。

2.编码格式实验

test_charset_ansi.c、test_charset_utf8.c 的编码格式分别为 ANSI、 UTF-8,它们的程序代码是一样的,如下:

(1)默认编码:

test_charset_ansi.c

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
        char *str = "A中";
        int i;

        printf("str's len = %d\n", (int)strlen(str));
        printf("Hex code: ");
        for (i = 0; i < strlen(str); i++)
        {
                printf("%02x ", (unsigned char)str[i]);
        }
        printf("\n");
        return 0;
}
cpp 复制代码
book@100ask:~/source/09_show_chinese$ gcc -o test_charset_ansi test_charset_ansi.c
book@100ask:~/source/09_show_chinese$ ./test_charset_ansi

test_charset_utf8.c

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
        char *str = "A中";
        int i;

        printf("str's len = %d\n", (int)strlen(str));
        printf("Hex code: ");
        for (i = 0; i < strlen(str); i++)
        {
                printf("%02x ", (unsigned char)str[i]);
        }
        printf("\n");
        return 0;
}
cpp 复制代码
book@100ask:~/source/09_show_chinese$ gcc -o test_charset_utf8 test_charset_utf8.c
book@100ask:~/source/09_show_chinese$ ./test_charset_utf8

不指定"-finput-charset "与"-fexec-charset "时,input-charset 和 exec-charset 默认都是 UTF-8,不会进行编码转换。即使 C 文件是 ANSI, 也会被认为是 UTF-8,所以不会导致编码转换

(2)指定编码格式

1)GB2312 转为 UTF-8
cpp 复制代码
book@100ask:~/source/09_show_chinese$ gcc -finput-charset=GB2312 -fexec-charset=UTF-8 -o test_charset_ansi test_charset_ansi.c

注意: 从上面的输出信息可以看出来,GB2312 的"0xd6 0xd0"可以转换为 UTF-8 的"0xe4 0xb8 0xad"

cpp 复制代码
book@100ask:~/source/09_show_chinese$ gcc -finput-charset=GB2312 -fexec-charset=UTF-8 -o test_charset_utf8 test_charset_utf8.c

注意: 而如果把原本就是 UTF-8 格式的 test_charset_utf8.c 当作 GB2312 格式,会引起错误。

2)UTF-8 转为 GB2312
cpp 复制代码
 book@100ask:~/source/09_show_chinese$ gcc -finput-charset=UTF-8 -fexec-charset=GB2312 -o test_charset_ansi test_charset_ansi.c

注意: 输 出 信 息 可 以 看 出 来 , 如 果 把 原 本 就 是GB2312 格式的 test_charset_ansi.c 当作 UTF-8 格式,会引起错误。

cpp 复制代码
 book@100ask:~/source/09_show_chinese$  gcc -finput-charset=UTF-8 -fexec-charset=GB2312 -o test_charset_utf8 test_charset_utf8.c
 book@100ask:~/source/09_show_chinese$ ./test_charset_utf8

注意:UTF-8 格式的"中"编码值为"0xe4 0xb8 0xad",可以转换为 GB2312 的"0xd6 0xd0"。

2.汉字区位码

我们从网上搜到 HZK16 这个文件,它是常用汉字的 16*16 点阵字库。HZK16 里每个汉字使用 32 字节来描述。

跟 ASCII 字库一样,每个字节中每一位用来表示一个像素,位值等于 1 时表示对 应像素被点亮,位值等于 0 时表示对应像素被熄灭。

HZK16 中是以 GB2312 编码值来查找点阵的,以"中"字为例,它的编码值 是"0xd6 0xd0",其中的 0xd6 表示"区码",表示在哪一个区:第"0xd6 - 0xa1" 区;其中的 0xd0 表示"位码",表示它是这个区里的哪一个字符:第"0xd0 - 0xa1"个。每一个区有 94 个汉字。区位码从 0xa1 而不是从 0 开始,是为了兼 容 ASCII 码。

所以,我们要显示的"中"字,它的 GB2312 编码是 d6d0,它是 HZK16 里第"(0xd6-0xa1)*94+(0xd0-0xa1)"个字符。

(1)打开汉字库文件

cpp 复制代码
4787     fd_hzk16 = open("HZK16", O_RDONLY);
4788     if (fd_hzk16 < 0)
4789     {
4790         printf("can't open HZK16\n");
4791         return -1;
4792     }
4793     if(fstat(fd_hzk16, &hzk_stat))
4794     {
4795         printf("can't get fstat\n");
4796         return -1;
4797     }
4798     hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);
4799     if (hzkmem == (unsigned char *)-1)
4800     {
4801         printf("can't mmap for hzk16\n");
4802         return -1;
4803     }

第 4787 行打开当前目录的字库文件:HZK16

第 4793 行获得文件的状态信息,里面含有文件长度,这在后面的 mmap 中用到

第 4798 行使用 mmap 映射文件 ,以后就可以像访问内存一样读取文件内容; mmap 的返回结果保存在 hzkmem 中,它将作为字库的基地址

(2)编写显示汉字的函数

核心函数是 void lcd_put_chinese(int x, int y, unsigned char *str) ,它在 LCD 的(x,y)位置处显示汉字字符 strstr0中保存区码str1 中保存位码

cpp 复制代码
4732 void lcd_put_chinese(int x, int y, unsigned char *str)
4733 {
4734     unsigned int area  = str[0] - 0xA1;
4735     unsigned int where = str[1] - 0xA1;
4736     unsigned char *dots = hzkmem + (area * 94 + where)*32;
4737     unsigned char byte;
4738
4739     int i, j, b;
4740     for (i = 0; i < 16; i++)
4741         for (j = 0; j < 2; j++)
4742         {
4743             byte = dots[i*2 + j];
4744             for (b = 7; b >=0; b--)
4745             {
4746                 if (byte & (1<<b))
4747                 {
4748                     /* show */
4749                     lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */
4750                 }
4751                 else
4752                 {
4753                     /* hide */
4754                     lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */
4755                 }
4756             }
4757         }
4758 }

第 4734 行确定该汉字属于哪个区

第 4735 行确实它是该区中哪一个汉字

第 4736 行确实它的字库地址:每个区中有 94 个汉字,每个汉字在字库中占据 32 字节。

需要根据图来理解第 4740 行开始的循环:

第 4740 行 汉字点阵排布的示意图,总共有十六行,因此需要一个循环 16 次的大循环

第 4741 行 考虑到一行有两个字节,在大循环中加入一个 2 次的循环用于区分是哪个字节

第 4744 行 使用第 3 个循环来处理一个字节中的 8 位 。对于每一位, 它等于 1 时对应的像素被设置为白色,它等于 0 时对应的像素被设置为黑色。需 要注意的是根据 x、y、i、j、b 来计算像素坐标。

(3) 使用 lcd_put_chinese 函数

cpp 复制代码
4760 int main(int argc, char **argv)
4761 {
4762     unsigned char str[] = "中";
4763
4764     fd_fb = open("/dev/fb0", O_RDWR);
4765     if (fd_fb < 0)
4766     {
4767         printf("can't open /dev/fb0\n");
4768         return -1;
4769     }
4770
4771     if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
4772     {
4773         printf("can't get var\n");
4774         return -1;
4775     }
4776
4777     line_width  = var.xres * var.bits_per_pixel / 8;
4778     pixel_width = var.bits_per_pixel / 8;
4779     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
4780     fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
4781     if (fbmem == (unsigned char *)-1)
4782     {
4783         printf("can't mmap\n");
4784         return -1;
4785     }
4786
4787     fd_hzk16 = open("HZK16", O_RDONLY);
4788     if (fd_hzk16 < 0)
4789     {
4790         printf("can't open HZK16\n");
4791         return -1;
4792     }
4793     if(fstat(fd_hzk16, &hzk_stat))
4794     {
4795         printf("can't get fstat\n");
4796         return -1;
4797     }
4798     hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);
4799     if (hzkmem == (unsigned char *)-1)
4800     {
4801         printf("can't mmap for hzk16\n");
4802         return -1;
4803     }
4804
4805     /* 清屏: 全部设为黑色 */
4806     memset(fbmem, 0, screen_size);
4807
4808     lcd_put_ascii(var.xres/2, var.yres/2, 'A'); /*在屏幕中间显示8*16的字母A*/
4809
4810     printf("chinese code: %02x %02x\n", str[0], str[1]);
4811     lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);
4812
4813     munmap(fbmem , screen_size);
4814     close(fd_fb);
4815
4816     return 0;
4817 }

四、编译程序与上机测试

1.编译命令:

cpp 复制代码
book@100ask:~/source/09_show_chinese$ arm-buildroot-linux-gnueabihf-gcc -fexec-charset=GB2312 -o show_chinese show_chinese.c
book@100ask:~/source/09_show_chinese$ cp show_chinese HZK16 ~/nfs_rootfs/  

**注意:**不同的板子,编译工具的前缀可能不一样。

注意:使用上述命令时 show_chinese.c 的编码格式必须是 ANSI(GB2312) ,否则编译时需要指定**"-fexec-charset=GB2312"**。

2.上机实验

把 show_chinese 程序放到板子上,执行命令:./show_chinese 。如果实验成功,我们将看到屏幕中间会显示出一个白色的字母"A"和"中"。

cpp 复制代码
[root@100ask:~]#  mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
[root@100ask:~]#  cp /mnt/show_chinese .
[root@100ask:~]#  cp /mnt/HZK16 .

3.实验效果 :

相关推荐
A小辣椒20 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言