当前位置: 首页 > news >正文

新华网站建设盘龙网站建设公司

新华网站建设,盘龙网站建设公司,写文章wordpress,asp.net 知名网站文章目录#xff1a;文件相关知识C语言文件IOstdin stdout stderr系统文件 IOopenclosewriteread文件描述符文件描述符的分配规则重定向dup2系统调用FILEFILE中的文件描述符FILE中的缓冲区理解文件相关知识 文件 文件内容 文件属性#xff08;每一个已经存在的… 文章目录文件相关知识C语言文件IOstdin stdout stderr系统文件 IOopenclosewriteread文件描述符文件描述符的分配规则重定向dup2系统调用FILEFILE中的文件描述符FILE中的缓冲区理解文件相关知识 文件 文件内容 文件属性每一个已经存在的文件都有其相应的属性来标识该文件空文件也有。文件的操作 文件内容的操作 | 文件属性的操作在对文件的内容进行操作时文件的属性也可能会改变。文件分为两类内存文件和磁盘文件。通常打开文件、访问文件、关闭文件都是由谁了进行相关操控的呢fopen、fwrite、fclose 操控程序当执行程序进程运行起来的时候才是对文件进行真正的操作文件操作的本质是进程和被打开文件之间的关系。什么是当前路径如下所示cwdcurren work directory所指向的路径就是当前路径。当前路径不是指可执行程序所处的路径而是指该可执行程序运行时所处的路径。 C语言文件IO 在之前我们对文件进行了简单的介绍具体可看C语言文件操作 下面来回顾一下C语言文件的基本操作 #includestdio.h #includesys/types.h #includeunistd.hint main() {// 不更改文件路径情况下文件默认在当前路径下形成chdir(/home/hy/linux_code); //更改当前进程的工作路径生成的文件就在已更改的路径下FILE* fp fopen(log.txt,w); //文件以w的方式打开文件不存在则创建一个若文件存在则先对文件进行清空if(fp NULL) {perror(fopen);return 1;}const char* msg hello file;int cnt 1;while(cnt 10){fprintf(fp,%s : %d\n,msg,cnt);}fclose(fp);return 0; }打开文件的方式 用文件操作实现简单的 cat 功能 #includestdio.h #includesys/types.h #includeunistd.h// myfile filename int main(int argc,char* argv[]) {if(argc ! 2) //判断输入格式是否正确{printf(usage: %s filename\n,argv[0]); //提示正确的使用方法return 1;}// 将输入的第二个参数的内容读入文件中FILE* fp fopen(argv[1],r);if(fp NULL){perror(fopen);return 1;}char buffer[64];while(fgets(buffer,sizeof(buffer),fp)!NULL) //将文件中的内容读到buffer中{printf(%s,buffer);}return 0; }stdin stdout stderr 在 Linux 下一切皆文件。所以显示器和输入键盘也看作是文件。我们能看到显示器上的数据是因为我们向显示器文件中写入了对应的数据。电脑能够从键盘中读取我们输入的数据。那为什么我们向显示器文件写入数据以及从键盘文件读取数据前不需要打开这两个文件呢 任何进程运行时都会默认的打开三个数据流stdin、stdout、stderr。 stdin - 标准输入流 - 通常对应终端的键盘stdout - 标准输出流 - 终端显示器stderr - 标准错误流 - 终端显示器 查询 man 手册可以发现stdin、stdout、stderr 这三个流的类型都是 FILE* 。 进程从标准输入文件中得到输入数据将正常输出数据输出到标准输出文件而将错误信息送到标准错误文件中。 输出信息到显示器的方法 #includestdio.h #includestring.hint main() {const char* msg hello fwrite!\n;fwrite(msg,strlen(msg),1,stdout);printf(hello printf\n);fprintf(stdout,hello fprintf\n);return 0; }系统文件 IO 操作系统除了语言级层面的函数接口c/c语言Java语言接口等外还有一套系统接口来进行文件的访问及操作。 write 写入数据read 读取数据open 打开文件close 关闭文件 以上接口都是用于系统层面而非用户层面的。 C语言中的函数如 fopen、fwrite、fclose 等我们都比较熟悉而系统层面的接口如 open、write、close 等接口都比较少用。相比于库函数而言系统接口更接近底层。但实际上语言层面的库函数就是对系统接口进行了封装 从开发角度看操作系统对外表现为一个整体会提供部分接口以供上层用户的调用 系统调用。但是系统接口相对而言比较复杂使用成本很高不利于上层开发人员的使用。所以我们对一些系统接口进行了适当的封装封装后的接口就是各个语言的库函数。 简单而言fwrite 函数是使用系统接口 write 进行封装的系统调用 write 只有一个相关的库函数都是建立在 write 等接口进行封装的。这样使得语言具有了跨平台性便于进行二次开发。 接下来简单介绍一下系统接口便于从底层更深入的了解IO。 open 操作系统中打开文件的接口是 open , open 的头文件和函数定义如下 #includesys/types.h #includesys/stat.h #includefcntl.hint open(const char *pathname,int flags); int open(const char *pathname,int flags,mode_t mode);参数说明 pathname: 要打开或创建的目标文件。 若 pathname 传入的是特定的路径则就在 pathname 所给出的路径下创建目标文件。若 pathname 传入的是文件名则就在当前路径下创建目标文件。 flags: 表示打开文件的方式。打开文件时可以传入多个参数选项用下面的一个或者多个常量进行 “或” 运算构成 flags。以 | 进行分割。 常用选项如下所示 参数选项说明O_RDONLY以只读的方式打开文件O_WRONLY以只写的方式打开文件O_RDWR以读写的方式打开文件O_CREAT当文件不存在时创建该文件O_APPEND以追加的方式写入文件O_TRUNC如果文件存在且该文件运行写入就将文件进行清空 mode: open 函数具体使用哪一个和具体应用场景有关若目标文件不存在需要使用 open 进行创建则第三个参数表示创建文件的默认权限否则就使用两个参数的 open 函数。使用 open 创建新文件时若不传入默认的权限则权限是乱的。 例如将 0666 传入 mode 参数则创建出来的文件权限为-rw-rw-rw-但是创建出来的文件的实际权限还受默认权限掩码 umask 的限制实际上文件创建出来的权限为mode(~umask)。umask 在普通用户下一般为 0002 因此将 0666 传入 mode 参数时创建的新文件的实际权限为:-rw-rw-r--。这并不是我们想要的。 若想要创建出来的新文件不受默认权限掩码 umask 的影响我们可以在调用 open 接口前将 umask 在程序中设置为 0。 umask(0); //将文件的默认权限设置为0返回值 成功返回新打开的文件描述符失败返回 -1 open 的第二个参数传入的是宏那么宏的实现基本原理是什么呢第二个参数的类型是 int 有 32 个比特位实际上一个比特位可以作为一个标志位。flags 的每一个选项都是以宏的方式定义的。 接下来看一个例子理解一下宏实现的基本原理 #includestdio.h// 可以用比特位标志不同的宏定义如下所示 #define PRINT_A 0x1 //0000 0001 #define PRINT_B 0x2 //0000 0010 #define PRINT_C 0x4 //0000 0100 #define PRINT_D 0x8 //0000 1000 #define PRINT_DEF 0x0 void Show(int flags) {if(flags PRINT_A) printf(A\n);if(flags PRINT_B) printf(B\n);if(flags PRINT_C) printf(C\n);if(flags PRINT_D) printf(D\n);if(flags PRINT_DEF) printf(Default\n); }int main() {printf(PRINT_DEF:\n);Show(PRINT_DEF);printf(PRINT_A:\n);Show(PRINT_A);printf(PRINT_B:\n);Show(PRINT_B);printf(PRINT_A and PRINT_B:\n);Show(PRINT_A | PRINT_B);printf(PRINT_c and PRINT_D:\n);Show(PRINT_C | PRINT_D);printf(PRINT all:\n);Show(PRINT_A | PRINT_B | PRINT_C | PRINT_D);return 0; }运行结果如下所示 close 系统接口 close 用于关闭文件。close 接口的定义和头文件如下 #includeunistd.hint close(int fd); // fd文件描述符是打开文件时的返回值返回值 close 关闭文件成功则返回 0 。若出现错误则返回 -1并适当的设置 errno。 write 系统接口 write 用于向文件中写入数据write 接口的定义和头文件如下 #includeunistd.hssize_t write(int fd,const void* buf,size_t count); // 使用write接口将buf中count字节的数据写入文件描述符为fd的文件中返回值 数据写入成功时返回写入的字节数零表示没有写入任何字节。数据写入出错时则返回 -1并适当的设置 errno。 示例 #includestdio.h #includefcntl.h #includesys/types.h #includesys/stat.h #includestring.h #includeunistd.hint main() {umask(0);//设置默认权限掩码为0int fd open(log.txt,O_WRONLY | O_CREAT | O_TRUNC,0666);//int fd open(log.txt,O_WRONLY | O_CREAT | O_APPEND,0666);if(fd 0){perror(open);return 1;}const char* msg hello file\n;int count 0;while(count 5){write(fd,msg,strlen(msg)); // msg:缓冲区首地址;len:本次读取期望写入多少个字节的数据;返回值实际写了多少字节数据count;}close(fd);return 0; }运行结果如下 ❗注意向文件中写入数据时不需要写入 ‘\0’。它是C语言规定的字符串结束标志系统IO没有规定。因此只要将有效字符写入即可。write 的第二个参数类型为 void* 意味着系统不在意写入的类型我们需要什么类型数据就转换为什么类型再写入/ read 系统接口 read 用于从文件中读取数据read 接口的定义和头文件如下 #includeunistd.hssize_t read(int fd,void *buf,size_t count); // 从文件描述符为fd的文件中读取count字节数据到buf中返回值 如果读取数据成功将返回读取的字节数0表示文件结束如果count大于文件的数据字节数则不是错误直接读取完文件。如果读取数据错误则返回 -1并适当设置 errno。 示例 #includestdio.h #includefcntl.h #includesys/types.h #includesys/stat.h #includestring.h #includeunistd.hint main() {int fd open(log.txt,O_RDONLY); //读取文件的前提是文件已经存在所以不涉及权限和创建文件的问题if(fd 0){perror(open);return 1;}char buffer[128];ssize_t s read(fd,buffer,sizeof(buffer)-1);if(s 0){buffer[s] \0; printf(%s,buffer);}close(fd);return 0; }运行结果如下 文件描述符 文件描述符是操作系统内核中用于标识一个进程正在访问的文件或其它输入/输出资源的正整数。在 unix/linux 系统中文件、管道、套接字、块、设备等资源都被视为文件每一个打开的文件都会被分配一个唯一的文件描述符。 文件是由进程运行时打开的一个进程可以打开多个文件而系统中存在着大量的进程因此系统中可能存在大量被打开的文件。如此多的文件操作系统是怎样对它们进行管理的呢操作系统会给每个打开的文件分配一个 struct file(表示文件的结构体) 结构体对象用于记录该文件的各种属性和状态信息。然后将这些结构体对象用双链表组织起来将对文件结构体的操作转换为对双链表的操作。 struct file 结构体通常包括以下成员 struct file_operations *f_op指向用于操作该文件的函数指针表mode_t f_mode表示该文件的访问权限loff_t f_pos表示当前读写位置的偏移量-unsigned int f_flags表示文件打开时的标志位struct address_space *f_mapping表示该文件的内存映射关系struct inode *f_inode表示该文件所关联的索引节点inode。 除上述成员外struct file 结构体还包含一些其它的成员变量如文件描述符、私有数据等。通过 struct file 结构体内核可以对打开的文件进行管理和控制如读取文件内容、修改文件属性、更改文件状态等。 计算机通常会运行多个进程而每个进程都可能打开其特定的文件那么计算机是如何识别文件分别对应哪一个进程呢当一个进程运行时操作系统会将该进程的代码和数据加载到内存中然后创建对应的 task_struct、mm_struct、页表等相关的数据结构和进程信息在 task_struct 中有一个特定的指针指向 file_struct 的结构体用该结构体来维护进程与文件之间的关系该结构体中包含了一个名为 struct file* fd_array[] 的结构体指针数组进程打开的文件地址就会填入此数组中这个指针数组中存储的下标就是所谓的文件描述符。 当我们需要对文件进行操作的时候可以利用文件对应的文件描述符找到相应的文件然后对文件进行操作。 当调用open函数时的返回值是 fd这个 fd 就是该文件的文件描述符如下所示 观察该程序的运行结果发现这些已打开文件的文件描述符是一些从 3 开始的连续整数与数组下标非常类似但是没有 0、1、2 这三个数字。 实际上系统运行之后系统会默认打开三个标准输入/输出/错误流其中 0 号文件描述符表示标准输入stdin1 号文件描述符表示标准输出stdout2 号文件描述符表示标准错误stderr。程序可以通过重定向来改变这些默认的行为将它们指向其它的文件或者设备。 文件描述符就是从 0 开始的小整数。当我们打开文件时操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了 file 结构体。表示一个已经打开的文件对象。而进程执行 open 系统调用所以必须让进程和文件关联起来。每个进程都有一个指针 *files指向一张表 file_struct该表包含一个指针数组每个元素都是一个指向打开文件的指针本质上文件描述符就是该数组的下标。因此可通过文件描述符找到对应的文件。 文件描述符的分配规则 如下所示连续打开五个文件查看这5个文件对应的文件描述符: #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h int main() {int fd1 open(log1.txt,O_WRONLY | O_CREAT | O_TRUNC,0666);int fd2 open(log2.txt,O_WRONLY | O_CREAT | O_TRUNC,0666);int fd3 open(log3.txt,O_WRONLY | O_CREAT | O_TRUNC,0666);int fd4 open(log4.txt,O_WRONLY | O_CREAT | O_TRUNC,0666);int fd5 open(log5.txt,O_WRONLY | O_CREAT | O_TRUNC,0666);printf(fd1 : %d\n,fd1);printf(fd2 : %d\n,fd2);printf(fd3 : %d\n,fd3);printf(fd4 : %d\n,fd4);printf(fd5 : %d\n,fd5);return 0; }运行结果如下所示文件描述符通常是从小到大顺序分配的即先分配的文件描述符数值较小后分配的文件描述符数值较大。因为文件描述符的本质上是数组的下标 接下来我们将我们描述符的 0 和 2 关闭不要将 1 号文件描述符关闭因为 1 号文件描述符对应的是显示器文件stdout若关闭 1 号文件则程序运行的输出无法显示 由上面两个例子可以看出文件描述符的分配规则在 fd_array 数组中从 0 开始找一个没有使用过的下标分配给新打开的文件作为该文件的文件描述符。 重定向 什么是重定向呢接下来看一个例子了解一下重定向的基本原理。 例让原本输出到 “显示器文件” 的数据输出到文件 log.txt 中因此在程序运行起来先将文件描述符为 1 号的文件关闭然后打开 log.txt 文件那么这个文件所分配到的文件描述符就是 1 由程序运行结果发现本应该输出到显示器的数据输出到了 log.txt 文件中。这种现象就叫做输出重定向。即这段代码的主要作用就是将程序的标准输出stdout关闭并将其重定向到 “log.txt” 文件中。 输出重定向的基本原理 在默认情况下程序的标准输出会被直接发送到显示器终端上。当使用 “” 符号将其输出重定向到文件时操作系统会创建一个新的与该文件相关联的文件描述符并将原本与标准输出相关联的文件描述符重定向到该文件描述符上。这样程序输入的内容就写入到了指定的文件中。 在上述示意图中可以看到程序在执行过程中并没有改变它的标准输出方式而是将标准输出和文件描述符关联起来进行了重定向。这种方式可以让程序在不需要知道输出目标位置的情况下将输出信息写入到不同文件中提高了程序的灵活性和可扩展性。 注意:输入重定向和追加重定向的原理也类似这里就不展开说了。 下面观察一个这个代码的运行结果 #includeiostream #includecstdio #includeerrno.h #includecstringint main() {//stdoutprintf(hello printf 1\n);fprintf(stdout,hello fprintf 1\n);fputs(hello fputs 1\n,stdout);//stderrfprintf(stderr,hello fprintf 2\n);fputs(hello fputs 2\n,stderr);perror(hello perror 2);//coutstd::couthello cout 1std::endl;//cerrstd::cerrhello cerr 2std::endl;return 0; }运行结果如下所示; 标准输出和标准错误都是向显示器输出数据但可以将 stdout 输出的数据和 stderr 输出的数据分别重定向到对应的文件中。在终端环境下使用 符号将标准输出重定向到文件中使用 2 符号将标准错误重定向到文件中。目的是将程序的正常输出与程序的异常输出分别放在不同的文件中便于分析程序。 ❓那么 stdout 和 stderr 的主要区别在哪里呢为什么输出数据重定向到不同文件中 标准输出stdout是程序向用户提供反馈信息的一种方式。一般情况下stdout 被认为是程序的正常输出流用于输出普通信息、结果和警告等内容。标准错误stderr也是程序向用户提供反馈信息的一种方式。不同的是stderr 一般被认为是程序的异常输出流用于输出错误信息、调试信息和非正常信息。 若一个程序需要输出有用的信息给用户那么会将这些信息写入到标准输出中若程序出现异常的报错那么会将这些信息写入到标准错误中。这样用户就可以容易的分辨出哪些是正常的输出哪些是异常的输出从而更好的了解程序的运行情况。 dup2系统调用 dup2 是一个 unix/linux 系统调用用于复制一份已存在的文件描述符oldfd到另一个文件描述符newfd上这样它们就共享一个表项file table entry。这个新的文件描述符指向原有的文件但是它有一个不同的文件描述符号码file descriptor number。使用 dup2 系统调用可以实现输入输出重定向、管道通信等功能。 ✴️函数原型 #includeunistd.hint dup2(int oldfd,int newfd);✴️函数返回值 若 dup2() 调用成功则返回 newfd 否则返回 -1并设置 errno 变量。 ✴️说明 dup2() 使 newfd 成为 oldfd 的一份拷贝如有必要需首先关闭 newfd 但是需要注意以下事项 如果 oldfd 不是有效的文件描述符则调用失败newfd 不会关闭。如果 oldfd 是一个有效的文件描述符而 newfd 和 oldfd 具有相同的值则 dup2() 不做任何事情并返回 newfd。 示例 #includestdio.h #includefcntl.h #includeunistd.hint main() {int fd open(file.txt,O_WRONLY | O_CREAT | O_TRUNC,0644);if(fd -1){perror(open);return 1;}int new_fd dup2(fd,1); //拷贝到标准输出if(new_fd -1){perror(dup2);return 1;}printf(This is redirected to file.txt!\n); //输出到文件中close(fd);return 0; }运行结果如下所示 FILE FILE中的文件描述符 因为 IO 相关函数与系统调用接口对应并且库函数封装系统调用所以本质上访问文件都是通过 fd 访问的。因此 C 库当中的 FILE 结构体内部必定封装了 fd。 在 /usr/include/stdio.h 头文件中可以看到 FILE 结构体FILE 结构体是 struct _IO_FILE 结构体的一个引用 struct _IO_FILE 是C语言标准 I/O 库中用于描述文件流的结构体。其中包含了一些与文件操作相关的信息如文件指针、缓冲区、状态位等。struct _IO_FILE 通常被实现为一个指向缓冲区的指针其中缓冲区可以是输入缓冲区和输出缓冲区也可以是二者兼备。其常见的成员变量及解释如下 _flags文件流的状态标志包括打开/关闭、读/写、是否出错、是否需要缓冲等信息。_IO_buf_base 和 _IO_buf_end指向输入/输出缓冲区的起始地址和结束地址。_fileno文件描述符file descriptor用于操作系统级别的文件接口。_IO_read_ptr 和 _IO_read_end指向输入缓冲区中已读数据和剩余未读数据的指针。_IO_write_ptr 和 _IO_write_end指向输出缓冲区中已写数据和剩余可写空间的指针。_IO_save_base 和 _IO_backup_base用于缓存当前位置的指针在遇到错误时可以回滚到之前的位置。_IO_lock 和 _lockcount用于多线程环境下的同步锁。 注意struct _IO_FILE 是标准库内部的实现细节不同的编译器可能会有所不同因此不要直接访问该结构体的成员变量。我们应该使用标准库提供的函数fopen、fclose、fread、fwrite等来对文件进行操作。 ❓在C语言中使用 fopen 函数时究竟发生了什么 当在C语言中使用标准 I/O 库函数 fopen 打开一个文件时该函数会返回一个指向 FILE 类型的指针。这个指针实际上是一个 FILE 结构体变量的地址在底层通过系统接口 fopen 打开对应的文件该文件被分配一个文件描述符(fd)然后将 fd 填到 FILE 结构体中的 _fileno 变量中然后完成文件的打开操作。 FILE中的缓冲区理解 首先来看看以下代码及其运行结果然后来理解缓冲区。 #include stdio.h #include unistd.hint main() {const char *str1 hello printf\n;const char *str2 hello fprintf\n;const char *str3 hello fputs\n;const char *str4 hello write\n;//c库函数printf(str1);fprintf(stdout,str2);fputs(str3,stdout);//系统接口write(1,str4,strlen(str4));//调用完上面指执行forkfork(); return 0; }运行程序时每一个函数对应的结果都输出在了显示器上。但是当将程序执行的结果重定向到 file.txt 文件中时结果发生了变化如下所示 在 file.txt 文件中C库函数打印的内容重定向到文件变为了两份而系统接口 write 输出的内容重定向到文件中也只有一份。这是为什么呢这里猜测可能与 fork 有关 分析在程序执行时每一个字符串后面都带有 ‘\n’因此数据打印到显示器所采用的是行缓冲的方式。因此当执行程序时数据被立即刷新到了显示器上。将运行结果重定向到普通文件时数据的缓冲方式由行缓冲变成了全缓冲。此时 fprintf、fputs、printf 函数打印的数据都先存储在了缓冲区中fork 之后父子数据会发生写时拷贝所以当父进程数据准备刷新时子进程也就有了同样的一份数据因此重定向到 file.txt 文件时fprintf、fputs、printf 函数输出的数据就有了两份。而 write 是系统调用库函数在系统调用的 “上层” 是对系统调用的 “封装” 但是 write 没有缓冲区因此 write 调用打印的数据只有一份。 什么是缓冲区❓ 缓冲区是内存空间的一部分。也就是说在内存中预留了一定的存储空间这些存储空间用缓冲输入或输出数据这部分预留的空间叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备分为输入缓冲区和输出缓冲区。 有几种类型的缓冲区❓ 缓冲区分为三种类型全缓冲、行缓冲和不带缓冲。 全缓冲当填满标准 I/O 缓冲后才进行实际 I/O 操作。全缓冲的典型代表是对磁盘文件的读写。 行缓冲当在输入和输出中遇到换行符时执行真正的 I/O 操作。这时输入的字符先存放在缓冲区等按下回车键换行时才进行真正的 I/O 操作。典型代表是键盘输入数据。 不带缓冲不进行缓冲标准出错情况 stderr 是典型代表让输出的数据立即显示出来。 为什么要有缓冲区❓ 缓和 CPU 与 I/O 设备将速度不匹配的矛盾减少中断 CPU 的频率放宽对 CPU 中断响应时间的限制。集中处理数据刷新减少 I/O 次数从而达到提高整机效率的目的。提高 CPU 和 I/O 设备之间的并行性。 这个缓冲区在哪里❓ 由以上代码及运行结果知write 系统调用接口是立即刷新的而C库函数是最后程序退出时刷新的。由此可知缓冲区不在系统内部而C 库函数输出的数据存放到了缓冲区。说明缓冲区是由C语言提供的在 FILE 结构体当中进行维护FILE 结构体中保存了程序缓冲区的相关信息。
文章转载自:
http://www.morning.nmrtb.cn.gov.cn.nmrtb.cn
http://www.morning.fpxsd.cn.gov.cn.fpxsd.cn
http://www.morning.rqxhp.cn.gov.cn.rqxhp.cn
http://www.morning.cwrnr.cn.gov.cn.cwrnr.cn
http://www.morning.rjrz.cn.gov.cn.rjrz.cn
http://www.morning.dxzcr.cn.gov.cn.dxzcr.cn
http://www.morning.sfgzx.cn.gov.cn.sfgzx.cn
http://www.morning.fkdts.cn.gov.cn.fkdts.cn
http://www.morning.bwygy.cn.gov.cn.bwygy.cn
http://www.morning.mqfhy.cn.gov.cn.mqfhy.cn
http://www.morning.dwdjj.cn.gov.cn.dwdjj.cn
http://www.morning.wmmtl.cn.gov.cn.wmmtl.cn
http://www.morning.stbhn.cn.gov.cn.stbhn.cn
http://www.morning.tgmfg.cn.gov.cn.tgmfg.cn
http://www.morning.kndyz.cn.gov.cn.kndyz.cn
http://www.morning.xkqjw.cn.gov.cn.xkqjw.cn
http://www.morning.prfrb.cn.gov.cn.prfrb.cn
http://www.morning.qnpyz.cn.gov.cn.qnpyz.cn
http://www.morning.rbkdg.cn.gov.cn.rbkdg.cn
http://www.morning.cmqrg.cn.gov.cn.cmqrg.cn
http://www.morning.yqkmd.cn.gov.cn.yqkmd.cn
http://www.morning.dpnhs.cn.gov.cn.dpnhs.cn
http://www.morning.nfmtl.cn.gov.cn.nfmtl.cn
http://www.morning.rfyk.cn.gov.cn.rfyk.cn
http://www.morning.npgwb.cn.gov.cn.npgwb.cn
http://www.morning.rxsgk.cn.gov.cn.rxsgk.cn
http://www.morning.gjwkl.cn.gov.cn.gjwkl.cn
http://www.morning.qgdsd.cn.gov.cn.qgdsd.cn
http://www.morning.mhsmj.cn.gov.cn.mhsmj.cn
http://www.morning.xgzwj.cn.gov.cn.xgzwj.cn
http://www.morning.jwtwf.cn.gov.cn.jwtwf.cn
http://www.morning.lrzst.cn.gov.cn.lrzst.cn
http://www.morning.hgbzc.cn.gov.cn.hgbzc.cn
http://www.morning.kxwsn.cn.gov.cn.kxwsn.cn
http://www.morning.wpjst.cn.gov.cn.wpjst.cn
http://www.morning.yldgw.cn.gov.cn.yldgw.cn
http://www.morning.bnxnq.cn.gov.cn.bnxnq.cn
http://www.morning.qytyt.cn.gov.cn.qytyt.cn
http://www.morning.fhkr.cn.gov.cn.fhkr.cn
http://www.morning.jyyw.cn.gov.cn.jyyw.cn
http://www.morning.rjmb.cn.gov.cn.rjmb.cn
http://www.morning.pwggd.cn.gov.cn.pwggd.cn
http://www.morning.fjlsfs.com.gov.cn.fjlsfs.com
http://www.morning.tyrlk.cn.gov.cn.tyrlk.cn
http://www.morning.jkcnq.cn.gov.cn.jkcnq.cn
http://www.morning.wfspn.cn.gov.cn.wfspn.cn
http://www.morning.qhczg.cn.gov.cn.qhczg.cn
http://www.morning.kbfzp.cn.gov.cn.kbfzp.cn
http://www.morning.attorneysportorange.com.gov.cn.attorneysportorange.com
http://www.morning.nwmwp.cn.gov.cn.nwmwp.cn
http://www.morning.slysg.cn.gov.cn.slysg.cn
http://www.morning.xbnkm.cn.gov.cn.xbnkm.cn
http://www.morning.fnssm.cn.gov.cn.fnssm.cn
http://www.morning.csnch.cn.gov.cn.csnch.cn
http://www.morning.dkfb.cn.gov.cn.dkfb.cn
http://www.morning.rrwft.cn.gov.cn.rrwft.cn
http://www.morning.zqbrw.cn.gov.cn.zqbrw.cn
http://www.morning.yjqkk.cn.gov.cn.yjqkk.cn
http://www.morning.tqsmg.cn.gov.cn.tqsmg.cn
http://www.morning.gqflj.cn.gov.cn.gqflj.cn
http://www.morning.rzmzm.cn.gov.cn.rzmzm.cn
http://www.morning.xkyfq.cn.gov.cn.xkyfq.cn
http://www.morning.fkmrj.cn.gov.cn.fkmrj.cn
http://www.morning.bmtyn.cn.gov.cn.bmtyn.cn
http://www.morning.xcszl.cn.gov.cn.xcszl.cn
http://www.morning.lmzpk.cn.gov.cn.lmzpk.cn
http://www.morning.mrfnj.cn.gov.cn.mrfnj.cn
http://www.morning.wpcfh.cn.gov.cn.wpcfh.cn
http://www.morning.ktxd.cn.gov.cn.ktxd.cn
http://www.morning.fnlnp.cn.gov.cn.fnlnp.cn
http://www.morning.gkjnz.cn.gov.cn.gkjnz.cn
http://www.morning.yuanshenglan.com.gov.cn.yuanshenglan.com
http://www.morning.qlpyn.cn.gov.cn.qlpyn.cn
http://www.morning.mbpzw.cn.gov.cn.mbpzw.cn
http://www.morning.cwyfs.cn.gov.cn.cwyfs.cn
http://www.morning.lgwjh.cn.gov.cn.lgwjh.cn
http://www.morning.dpfr.cn.gov.cn.dpfr.cn
http://www.morning.xbnkm.cn.gov.cn.xbnkm.cn
http://www.morning.dndjx.cn.gov.cn.dndjx.cn
http://www.morning.ntgrn.cn.gov.cn.ntgrn.cn
http://www.tj-hxxt.cn/news/244691.html

相关文章:

  • 图书馆建设网站韩国外贸平台
  • wordpress的paypal插件江苏seo排名
  • 做电商网站微信号是多少网站在布局
  • 自定义内容网站建筑企业资质新规定2022
  • 自己搭建服务器访问国外网站中国女排联赛排名
  • 网站开发需求廊坊网站制作系统
  • 营销型网站功能怎么用ftp清空网站
  • 怎样做美瞳网站大型门户网站建设哪专业
  • 网站建设推广费计入什么科目网站的交互设计包括哪些
  • 建设企业网站官网企业网银网站建设怎么在png上写文字
  • 网站网页怎么设计wordpress开发复杂网站
  • 免费制作永久网站wordpress 文章带字段
  • 个人网站可以做地方外贸网站建设公司流程
  • 做网站怎么放视频宁波一网信息技术有限公司
  • 购物网站首页分成几个模块移动微网站建设二维码
  • 网站设计教程文档深圳返利网站建设
  • it网站开发wordpress怎么用二级域名
  • 百度seo可能消失河北seo诊断培训
  • 如何做网站淘客推广汉阴县住房和城乡建设局网站
  • 自己怎么制作企业网站合肥网络推广培训学校
  • 济南手机网站直播平台网站建设
  • ip设计网站微信朋友圈推广方案
  • 上海模板建站软件腾讯视频创作平台
  • 手机电脑网站设计网站增加关键词
  • 网站建设与管理自考试题及答案比较好的网站建设平台
  • 东莞是什么网站建设展览公司
  • 购物网站建设源码福建省建设执业注册中心网站
  • 百度推广必须做手机网站吗网站开发毕业设计任务书范文
  • 烟台免费网站建站模板网站双线主机优势
  • 帮客户做网站的公司武穴建设网站