Linux-C 文件操作

一、简述

二、系统I/O

三、标准I/O

四、标准输入/输出重定向

五、文件操作补充

六、上述文件操作函数代码示例

一、简述

**

    基于Linux环境下C语言编程的文件操作。两种操作文件的方式:1、系统I/O:系统调用接口,`open(), read(), write(), lseek(), close()`。是操作系统直接提供的编程接口(API)。2、标准/IO:标准库的I/O函数,fopen(), fread(), fwrite(), fseek(), fclose(),是对系统调用接口进一步封装。系统I/O常用于硬件级别,可以设置读缓冲区,一般没有写缓冲区;标准I/O常用于软件级别,自带读写缓冲区。

1、文件基本概念
C程序把文件分为ASCII文件和二进制文件,ASCII文件又称文本文件,二进制文件和文本文件(也称ASCII码文件)二进制文件中,数值型数据是以二进制形式存储的,

而在文本文件中,则是将数值型数据的每一位数字作为一个字符以其ASCII码的形式存储,因此,文本文件中的每一位数字都单独占用一个字节的存储空间,

而二进制文件则是把整个数字作为一个二进制数存储的,并非数值的每一位数字都占用单独的存储空间,无论一个C语言文件的内容是什么,

它一律把数据看成是字节构成的序列,即字节流,对文件的存取也是以字节为单位的,输入/输出的的数据流仅受程序控制而不受物理符号(如回车换行符)的控制,所以说C语言文件为流式文件

C语言的文件存取有两种方式:顺序存取和直接存取

(C语言有缓冲型和非缓冲型两种文件系统,缓冲型文件系统是指系统自动自动在内存中为每一个正在使用的文件开辟一个缓冲区,

作为程序与文件之间数据交换的中间媒介,也就是读文件时,数据先送到缓冲区,再传给C语言程序或则外存上,缓冲文件系统利用文件指针标识文件,

而非缓冲文件系统是不会自动设置文件缓冲区,缓冲区必须由程序员自己设定,缓冲型中的文件操作,也称高级文件操作,

高级文件操作函数大多是ANSIC定义的可移植的文件操作函数,具有跨平台和可移植能力,可解决大多数文件操作问题)

##二、系统I/O

   **2.1 open()函数**

功能 打开一个指定的文件并获得文件描述符,或者创建一个新文件

头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
原型int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);

***参数***
pathname    要打开的文件路径名称
**flags**
O_RDONLY        只读方式打开文件    这三个参数互斥
O_WRONLY        只写方式打开文件
O_RDWR      读写方式打开文件
O_CREAT     如果文件不存在,则创建该文件
O_TRUNC     如文件已经存在,则删除文件中原有数据
O_APPEND    以追加方式打开文件
mode    如果文件被新建,指定其权限为mode(八进制表示法)
返回值 成功  大于等于0 的整数(即文件描述符)
失败  -1,并且errno会被设置**补充说明:**1)flags 的各种取值可以用位或的方式叠加起来,例如创建文件的时候需要满足这样的
选项:读写方式打开,不存在要新建,如果存在了则清空。则flags 的取值应该是:O_RDWR | O_CREAT | O_TRUNC。
2)mode 是八进制权限,比如0644,或者0755 等。也可以是使用系统已定义的S_IRWXU  00700 user (file owner) has read,  write,  and  execute permission //用户可读写执行权限S_IRUSR  00400 user has read permission//用户写权限S_IWUSR  00200 user has write permission//用户写权限S_IXUSR  00100 user has execute permission//用户执行权限      (更多选项可查询man手册:man 2 open)比如新创建的文件权限只需要读写权限:S_IRUSR  | S_IWUSR  **3)文件描述符**其实是一个数组的下标值,在内核中打开的文件是用 file 结构体来表示的,每一个结构体都会有一个 指针来指向它们,这些指针被统一存放在一个叫做 fd_array 的数组当中,而这个数组被存 放在一个叫做 files_struct 的结构体中,该结构体是进程控制块 task_struct 的重要组成部分。**2.2 close()函数**功能:关闭文件并释放相应资源

头文件

#include <unistd.h>


原型

int close(int fd);

    **参数**        fd 要关闭的文件的描述符

返回值
成功
0
失败
-1


备注重复关闭一个已经关闭了的文件或者尚未打开的文件是安全的。**2.3 read()函数**功能从指定文件中读取数据

头文件

#include <unistd.h>


原型ssize_t read(int fd, void *buf, size_t count);参数

fd

从文件 fd 中读数据,(fd是某个文件的描述符)


buf
指向存放读到的数据的缓冲区,(就是放数据的内存首地址)

count
想要从文件 fd 中读取的字节数


返回值
成功
实际读到的字节数
失败
-1


备注
实际读到的字节数小于等于 count

补充说明:

 ssize_t :是类型重定义,为了跨平台兼容。比如说long在32位系统可能是4字节,64位系统可能是8字节,嵌入式开发有的只有16位,那么int只有2个字节。

但是在编程时往往需要根据类型大小来进行操作数据,例如在64位系统编程时8字节使用long类型,如果移植到32位系统时long只有4字节,那么就需要改动好多个地方,所以重定义一种类型,然后根据实际系统再指定,方便改动移植。例如:重定义ssize类型是8字节的,在32位系统,我可以将long long重定义为ssize类型,如果是64位系统可以定义为long类型,这样只需改动一处。

**2.4 write()函数**功能将数据写入指定的文件

头文件

#include <unistd.h>


**原型**ssize_t write(int fd, const void *buf, size_t count);**参数**

fd
将数据写入到文件fd 中 (fd是某个文件的描述符)


buf
指向即将要写入的数据,(要写的数据的内存首地址)

count
要写入的字节数


返回值
成功
实际写入的字节数
失败      :            -1

备注
实际写入的字节数小于等于 count


**2.5 lseek()函数**功能调整文件位置偏移量

头文件

#include <sys/types.h>

#include <unistd.h>


原型off_t lseek(int fd, off_t offset, int whence);
**参数**
fd要调整位置偏移量的文件的描述符

offset

相对基准点的偏移大小

`
whence:基准点

SEEK_SET:文件开头处

SEEK_CUR:当前位置

SEEK_END:文件末尾处


返回值
成功
新文件位置偏移量(相对于文件开头的偏移)失败
-1备注
可用 file-size= lseek(fd,0,SEEK_END);来测量文件大小示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char* argv[])
{
int fd;
int wr_ret;
int rd_ret;
unsigned long file_size;
char wr_buf[100] = “hello world”;
char rd_buf[100];

fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH);//等价于fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, 0x604);
if(fd == -1)
{perror("open file error:");//只有上面的函数设置了error全局错误号,才可使用,会根据error输出对应的错误信息return -1;
}
printf("fd = %d\n", fd);wr_ret = write(fd, wr_buf, sizeof(wr_buf));
if(wr_ret == -1)
{perror("write file error:");return -1;
}
printf("wr_ret = %d\n", wr_ret);lseek(fd, 0, SEEK_SET);//上面的写操作,文件位置偏移量也会相应的移动,此处将文件偏移到文件开始位置,然后才能读取刚刚输入的内容
rd_ret = read(fd, rd_buf, sizeof(rd_buf));
if(rd_ret == -1)
{perror("read file error:");return -1;
}
printf("rd_ret = %d\n",rd_ret);
printf("content=%s\n", rd_buf);file_size = lseek(fd, 0, SEEK_END);
printf("file_size = %lu\n", file_size);close(fd);//关闭文件return 0;

}

     **2.5 mmap()函数**功能将物理内存映射为虚拟内存,为了提高效率。(比如将一个文件映射到虚拟内存,以操作内存的方式进行数据的读写,但是不会改变文件的大小,一般不用于普通文件)
头文件#include <sys/mman.h>
原型void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);**参数**addr    从虚拟内存的哪个地址开始去映射这片内存NULL代表由系统决定映射起始地址
length  映射的内存长度(字节为单位)
port决定这块内存的操作权限,以下数值可以相或PROT_EXEC  Pages may be executed.  执行权限PROT_READ  Pages may be read.      读权限PROT_WRITE Pages may be written.   写权限PROT_NONE  Pages may not be accessed.  无权限flags   操作标志MAP_SHARED:在多进程中把这块内存共享给其他进程    MAP_PRIVATE:不共享内存
fd将数据写入到文件fd 中 (fd是某个文件的描述符)
offset基于文件头偏移多少单位开始映射返回值
成功成功返回映射的虚拟地址
失败失败返回MAP_FAILED,其实就是个-1, errno会被设置备注取消映射   int munmap(void *addr, size_t length);addr:映射的起始地址length:取消的长度成功返回0,失败返回-1更多请查看man手册:man 2 mmap示例代码:

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h> //mencpy()

int main(void)
{
int fd;
char *map_ptr;

int retval;fd = open("a.txt",O_RDWR);
if(fd == -1)
{perror("open failed:");return -1;
}map_ptr = mmap( NULL, 100, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(map_ptr == MAP_FAILED)
{perror("map memory failed:");return -1;
}printf("%s", map_ptr);memcpy(map_ptr, "haha", 5);retval = munmap(map_ptr, 100);
if(retval == -1)
{perror("munmap failed:");return -1;
}close(fd);return 0;

}

**三、标准I/O****3.1 fopen()函数**功能获取指定文件的文件指针头文件#include <stdio.h>原型FILE *fopen(const char *path, const char *mode);**参数**path要打开的文件的路径名称mode“r” : 以只读方式打开文件,要求文件必须存在。
“r+” : 以读写方式打开文件,要求文件必须存在。“w” :  以只写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。“w+” :  以读写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。“a” : 以只写方式打开文件,文件如果不存在将会创建新文件,且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)。“a+” : 以读写方式打开文件,文件如果不存在将会创建新文件,第一次用于写数据则文件位置偏移量被自动定位到文件末尾(即以追加方式写数据),如果第一次用于读数据,文件位置偏移位置会定位到文件开始。返回值成功
文件指针失败  NULL备注
返回的文件指针是一种指向结构体 FILE{}的指针,文件描述符就被封装在FILE结构体里面程序一开始默认打开3个文件设备文件描述符(int)文件指针(FILE *)标准输入设备(键盘)0STDIN_FILENOstdin标准输出设备(屏幕)1STDOUT_FILENOstdout标准出错设备(屏幕)2STDERR_FILENOstderr**3.2 fclose()函数**功能关闭指定的文件并释放其资源头文件#include <stdio.h>原型int fclose(FILE *fp);**参数**fp即将要关闭的文件返回值成功0失败EOF备注fclose( )不能对一个文件重复关闭**3.3 fread()函数**功能从指定文件读取若干个数据块头文件#include <stdio.h>原型size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);**参数**ptr自定义缓冲区指针,(通俗的说就是要存放 读取出来的数据 的地方)size 数据块大小nmemb数据块个数stream即将被读取数据的文件指针
返回值成功读取的数据块个数,等于 nmemb失败读取的数据块个数,小于 nmemb 或等于 0备注当返回小与 nmemb 时,文件 stream 可能已达末尾,或者遇到错误3.4 fwrite()函数功能将若干块数据写入指定的文件头文件#include <sys/ioctl.h>原型size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);**参数**ptr:自定义缓冲区指针(要写入的数据的首地址)size:数据块大小nmemb:数据块个数stream:即将被写入数据的文件指针返回值成功写入的数据块个数,等于 sinmembze失败写入的数据块个数,小于 nmemb 或等于 0备注无3.5 fseek()函数功能设置指定文件的当前位置偏移量头文件#include <sys/ioctl.h>原型int fseek(FILE *stream, long offset, int whence);**参数**stream:需要设置位置偏移量的文件指针offset:新位置偏移量相对基准点的偏移whence:基准点SEEK_SET:文件开头处SEEK_CUR:当前位置SEEK_END:文件末尾处返回值成功0失败-1备注无3.6 ftell()函数功能获取指定文件的当前位置偏移量头文件#include <sys/ioctl.h>原型long ftell(FILE *stream);**参数**stream:需要返回当前文件位置偏移量的文件指针返回值成功当前文件位置偏移量失败-1备注无3.7rewind()函数功能将指定文件的当前位置偏移量设置到文件开头处头文件#include <sys/ioctl.h>原型void rewind(FILE *stream);**参数**stream:需要设置位置偏移量的文件指针返回值无备注该函数的功能是将文件 strean 的位置偏移量置位到文件开头处。简单例子:

#include <stdio.h>

int main(int argc,char* argv[])
{
int wr_ret;
int rd_ret;
FILE *fp;
unsigned long file_size;
char wr_buf[100] = “hello world”;
char rd_buf[100];

fp = fopen( "a.txt", "a+" );//文件追加,可读可写,文件不存在则创建
if(fp == NULL)
{perror("open file error:");//只有上面的函数设置了error全局错误号,才可使用,会根据error输出对应的错误信息return -1;
}wr_ret = fwrite( wr_buf, sizeof(wr_buf), 1, fp);
printf("wr_ret = %d\n", wr_ret);rewind(fp);//上面的写操作,文件位置偏移量也会相应的移动,此处将文件偏移到文件开始位置,然后才能读取刚刚输入的内容
rd_ret = fread(rd_buf, sizeof(rd_buf), 1, fp);
printf("rd_ret = %d\n",rd_ret);
printf("content=%s\n", rd_buf);fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
printf("file_size = %lu\n", file_size);fclose(fp);//关闭文件return 0;

}


———————————————
#**四、标准输入/输出重定向**
实际上,对于终端设备,系统会自动打开3个标准文件:标准输入、标准输出和标准错误输出,相应的,系统定义了3个特别的文件指针常数:stdin、stdout、stderr,分别指向标准输入、标准输出和标准错误文件,这3个文件都以标准终端设备作为输入/输出对象,在默认情况下,标准输入设备时键盘,标注输出设备是屏幕fprintf()是printf()的文件操作版,二者的差别在于fprintf()多了一个FILE *类型的参数fp,如果为其提供的第1个参数时stdout,那么它就和printf()完全一样,同理可推广到fputc()和putchar()等其他函数,例如:

putchar(c);和fputc(c,stdout);等价

getchar();和fgetc(stdin);等价

puts(str)和fputs(str,stdout);等价


但函数fgets()与gets()不同,从如下函数原型可知其区别在于fgets()还多了一个参数size

char *fgets(char *s,int size,FILE *stream);

char *gets(char *s)


;fgets()用其第二个参数size来说明输入缓冲区的大小,使读入的字符数不能超过限定缓冲区的大小,从而达到防止缓冲区溢出攻击的目的,假如已定义一个有32字节的缓冲区buffer[32],那么在下面两条读字符串的语句中,后者的安全性更高

gets(buffer);

fgets(buffer,sizeof(buffer),stdin);//安全性更高


虽然系统隐含的I/O是指终端设备,但其实标准输入和标准输出是可以重新定向的,操作系统可以重新定向它们到其他文件或具有文件属性的设备,只有标准错误输出不能进行一般的输出重定向,例如,在没有显示器的主机上,把标准输出定向到打印机,各种程序不用做任何改变,输出内容就自动从打印机输出这里用“<”表示输入重定向,用“>”表示输出重定向,例如:假设exefile时可执行程序文件名,执行该程序时,需要输入数据,现在如果要从文件file.in中读取数据,而非键盘输入,于是exefile的标准输入就被“<”重定向到了file.in,c此时程序exefile只会专心致志地从文件file.in中读取数据,而不再理会你此后按下的任何一个按键,于是,exefile的标准输出就被“>”重定向到了文件file.out中,此时程序exefile的所有输出内容都被输出到了文件file.out中,而屏幕上没有任何显示例:复制代码

1 #include <stdio.h>
2
3 main()
4 {
5 int c;
6
7 scanf_s("%d", &c);
8 printf("%d", c);
9
10 return 0;
11 }

将exe文件移到E盘,新建一个te.txt输入10然后保存,打开DOS命令行,转到E盘,输入test1.exe<te.txt回车,则te.txt文件中的10作为输入值,输出值为10#**五、文件操作补充**
因为在Microsoft Visual C++ 2010 Express中使用fopen,fscanf等函数编译器会显示警告,This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.所有在文件操作时将改用fopen_s、fscanf_s等函数fopen_s()函数函数原型:`errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );`pFile----文件指针将接收到打开文件指针指向的指针infilename----文件名mode----允许访问的类型fopen_s()打开文件成功返回0值,否则返回非0值须定义另外一个变量errno_t err例:

1 FILE *fp;
2 errno_t err;
3 err = fopen(&fp,“E:\ww.txt”,“r”);

这里的errno_t是int的别名,在编译器crtdef.h头文件中有typedef int errno_t;fopen()与fopen_s()的区别fopen_s()函数比fopen()函数多了一个溢出检测,安全性上有所提升,在使用形式上fopen_s()比fopen()多使用了一个参数,需要特别注意的是:fopen的返回值是FILE *,返回的是指向结构体类型的指针而fopen_s的返回值是errno_t,返回的是errno_t(int)类型的数值例:**fopen()函数**1 fp = fopen("E:\\ww.txt", "r");fopen_s()函数1 errno_t err;
2 err = fopen_s(&fp,"E:\\ww.txt","r");**fscanf_s()函数**函数原型:`fscanf_s(_Inout_ FILE * _File, _In_z_ _Scanf_s_format_string_ const char * _Format, ...);`fscanf_s和fscanf的区别在使用形式上fopen_s()比fopen()多使用了一个参数,第四个参数是字节数(注意长度(strlen)和字节数(sizeof)的区别)例:fscanf()函数1 fscanf(fp, "%c", &c);fscanf_s()函数1 fscanf_s(fp, "%c", &c,sizeof(char));#**六、上述文件操作函数代码示例**
(前提条件:在E盘根目录下新建一个txt文档命名为ww.txt,内容输入about保存)fopen()函数----fopen(文件路径, 文件使用方式);

1 FILE *fp;
2 fp = fopen(“E:\ww.txt”, “r”);

fopen_s()函数----fopen_s(指向该文件指针的指针, 文件路径, 文件使用方式);

1 errno_t err;
2 err = fopen_s(&fp, “E:\ww.txt”, “r”);

fread()函数----fread(内存首地址, 数据块大小, 数据块个数, 文件指针);

1 char ss[20];
2 fread(ss, sizeof(char), 4, fp);

fwrite()函数----fwrite(内存首地址, 数据块大小, 数据块个数, 文件指针);

1 char ss[20] = “aabb”;
2 fwrite(ss, sizeof(char), 4, fp);


fscanf_s()函数----fscanf_s(文件指针, 格式参数, 存入地址, 字节数)1 fscanf_s(fp, "%c", &c,sizeof(char));fprintf()函数----fprintf(文件指针, 格式参数, 输出列表)

1 char c = ‘a’;
2 fprintf(fp, “%c”, c);

fseek()函数----fseek(文件指针, 指针偏移量, 起始位置);

1 fseek(fp, sizeof(char), SEEK_SET);

fgets()函数----fgets(内存首地址, 字符数, 文件指针);

1 char ss[20];
2 fgets(ss, 20, fp);

fgetc()函数----fgetc(文件指针);

1 char ss[20];
2 ss[0] = fgetc(fp);
3 printf("%c", ss[0]);

fputc()函数----fputc(变量名, 文件指针)

1 int c = ‘a’;
2 fputc(c, fp);
也可写成

fputc(‘c’, fp);

fputs()函数----fputs(字符串, 文件指针)

1 char ss[20] = “aaaa”;
2 fputs(ss, fp);
也可写成

1 fputs(“aaaa”, fp);

Linux-C 文件操作相关推荐

  1. linux修改目录block信息,linux下文件操作inode,block的变化

    在"浅谈linux性能调优之三:分区格式化之前的考虑" http://my.oschina.net/sharelinux/blog/143522    一文中我说了inode与bl ...

  2. Linux的文件操作

    1. 文件操作系统的调用 Linux的文件操作系统调用(在Windows编程领域,操作系统提供的接口称为 API)涉及创建(create).打开(open).读写(read/write)和关闭(clo ...

  3. Linux内核文件操作

    Linux内核文件操作 前言 一.文件操作结构体 二.VFS之file_operations对象 1.文件打开filp_open 2.文件关闭filp_close 3.文件读取vfs_read 4.文 ...

  4. linux拷贝文件函数,linux下文件操作的各个函数

    作者:HoytEmail:hoytluo@21cn.com 前言: 我们在这一节将要讨论linux下文件操作的各个函数. 文件的创建和读写 文件的各个属性 目录文件的操作 管道文件 --------- ...

  5. 服务器LINUX查看文件操作

    LINUX查看文件操作 步骤命令如下: grep # 显示 key 所在行及前后5行grep -5 'key' filegrep -C 5 'key' file # 显示 key 所在行及前5行gre ...

  6. linux c 文件操作

    目录 一.简述 二.系统I/O 2.1 open()函数 2.2 close()函数 2.3 read()函数 2.4 write()函数 2.5 lseek()函数 2.6 mmap()函数 三.标 ...

  7. Linux C: 文件操作相关的系统调用

    一.常见的文件操作相关的系统调用 普通权限的系统调用 函数 说明 int access(char *pathname,int mode) 检查对某个文件的权限 int chdir(const char ...

  8. linux c文件操作,Linux C 文件的输入/输出操作

    10.1 文件I/O操作概述 在Linux系统中,文件I/O操作可以分为两类,一类是基于文件描述符的I/O操作,另一类是基于数据流的I/O操作. 10.1.1 文件描述符简介 在文件操作一章中,也经常 ...

  9. 【Linux】文件操作系统调用

    一. 文件描述符 在Linux下使用文件描述符来表示设备文件和普通文件.文件描述符是一个整型的数据,所有对文件的操作都通过文件描述符实现.文件描述符的范围是0~OPEN_MAX,系统中有3个已经分配的 ...

  10. linux驱动文件操作简单介绍

    1.设备号 主设备号标识设备对应的驱动程序,次设备号由内核使用,用于确定设备文件所指的设备. 通过次设备号获得一个指向内核设备的直接指针,也可将此设备号当作设备本地数组的索引. 设备编号用dev_t表 ...

最新文章

  1. 安卓怎么连接服务器的数据库文件,安卓怎么连接服务器的数据库文件
  2. [转]struts2处理.do后缀的请求
  3. OBS集成WebRTC
  4. 3 个相见恨晚的 Google Colaboratory 奇技淫巧!
  5. Boost:aligned delete对齐删除的测试程序
  6. 自动化创建tornado项目
  7. linux ruby作用域,浅谈ruby语言中的一些概念(lambda, proc, block)
  8. spring_boot的logback-spring.xml配置为什么 %d{yyyy-MM-dd} 不起作用
  9. 【转】linux时钟jiffies及其相关
  10. RAR Extractor Max for Mac(解压缩软件)
  11. 2018中南大学 计算机考研分数,中南大学2018年硕士研究生招生复试基本分数线
  12. 入坑Java_入坑Java的自学之路
  13. Tomcat开启为什么会秒退
  14. tf.constant
  15. 可达编程 单源最短路
  16. 服务器会话视图没有显示内容,举个栗子!Tableau 技巧(77):通过服务器视图的全屏实现多媒体展示...
  17. 2.12、系统修改-隐藏安卓系统的导航栏和状态栏
  18. uniapp离线打包具体步骤
  19. C++/python描述 898. 数字三角形 (四种实现方法)
  20. cobaltstrike--CHM、LNK钓鱼网站钓鱼

热门文章

  1. 种子编辑 android6,360种子编辑器安卓APK下载-360种子在线编辑器手机版下载v1.0 Android版-腾牛安卓网...
  2. 滨州智能dcs系统推荐_dcs系统厂家推荐
  3. 算法竞赛入门经典习题
  4. 中标麒麟linux系统微信安装,Linux安装wine微信安装和遇到的问题及解决方法
  5. 草图大师 2019 破解版|草图大师Sketchup pro 2019中文破解版64位下载 v19.0(附Sketchup 2019破解补丁)
  6. x79服务器主板装系统,【小白经历分享】华南X79 E5 2670+470D 成功装上双系统 【win10+Sierra10.12.6】...
  7. 一例智能网卡(mellanox)的网卡故障分析
  8. Axure 8.0破解版下载
  9. 教师计算机考试取得模块,2015年教师称计算机考试模块.doc
  10. ViewStub使用