VI的使用:
1.打开linux后按住ctrl+alt+t进入编程页面。
2.输入vi后回车进入进入命令行模式,然后按i进入输入模式看见左下
角有insert就可以编写代码了。在输入模式下按esc一直按到insert消失就退回命令行模式了。
3. 命令行模式下输入冒号(:)+w(保存)q(退出)在回车就退出
并保存代码了。
4.编译工具:gcc a.c -o a;a.c是要编译的c文件名,a是要生成的程序名,运行程序按(./程序名)如(./a)。
5.常用指令:*ls可以查看当前文件夹下有哪些文件, ls -a显示所有文件包括隐藏文件。 ls-l查看这个路径下所有文件的权限。
*pwd显示当前在那个文件夹下面。
*mkdir mkdir sp 创建一个文件夹,文件夹的名字是sp。
*cd cd sp 进入sp文件下。
*cd .. 退回上一层文件。
*tab键 自动补全,当文件名太长时输入前几个字符后按tab系统会自动补全后面的。
*mv 移动 mv *c sp 将所有c文件移动到sp文件夹中。
重命名 mv a.c b.c 将文件名a改为b。
*cp 拷贝 cp b.c test.c 将b.c中的内容拷贝到test.c中。
*touch wangkui 创建一个名为wangkui的空文件。
*ifconfig 查看ip地址。
*xrandr 查分辨率。 xrandr -s 分辨率 更改分辨率。
*rm file1 删除file1这个文件。
*rmdir 删除文件夹。
*close close(fd)关闭fd指代的文件。
* whereis ls 寻找ls这个指令所在的路径;
* date 获得系统的时间;
*echo $PATH 找到当前状态的环境变量;
*cat cat 文件名 在编译界面打开文件;
*ipcs -m 查看本路径下的共享内存;
*ipcrm -m 内存id 删除这个共享内存;
*ls -i 文件索引节点号;
*ls -a 查找当前文件;
*ls -ai 可以配合使用,消息队列求key值可以用。
*ps -aux|grep a.out 找出所有a.out进程
*kill -l 列出所有信号;
*kill -9 2044 结束pid为2044的进程
*chmod +x start.sh 给start.sh文件赋予可执行权限
*du a.out显示a.out文件的大小
*gpio readall 查看树莓派的IO口
*set nu 命令行模式下输入显示行号。
*unzip 文件名 解压当前文件。
*dmesg 查看外部设备接入虚拟机的状态。
linux系统操作api:
*打开 open 读写 write/read 光标定位 lseek 关闭 close
open函数原型:int open(const char *pathname, int flags);
pat为要打开的文件名;flags有三种命令:O-RDONLY 只读打开;
O-WRONLY 只写打开; O-RDWR 可读可写打开。
若要打开的文件不存在可以用这个函数创建一个新文件并打开。
int open(const char *pathname, int flags, mode_t mode);
r 可读 4 ; w 可写 2 ; x 执行 1 ; 0600给文件所有者权限6=4+2;
列:fd=open("./file1",O_RDWR|O_CREAT,0600);创建一个file1文件权限是0600;6表示可读可写。
-
另外三种命令:
*O_CREAT:若文件不存在创建他,并在后面跟一个mode参数,说明文件许可权限。
*O_EXCL :在与O-CREAT连用时如果要打开的文件已存在则会出错,若不存在则正常运行。
*O_APPEND:使文件写入时新输入的内容从原内容末尾开始,若没有新内容则从头开始覆盖原内容。
*O_TRUNC:此命令使写入时要打开的原文件中的内容被新内容全部替代,而不是覆盖。
7.文件的写入函数:ssize_t write(int fd, const void *buf, size_t count);
fd为open函数的返回值表示写入文件的返回值,指针buff指向写入容,后面是写入字符串的长度。他的返回值就是输入的字符长度strlen(buf);
8. 文件的读取操作:ssize_t read(int fd, void *buf, size_t count);
fd为打开文件的代码,buf指向的是从fd中读出的内容,count是要读出的长读字节数,他的返回值就是读出的长度。
9.文件写入完成后光标在字符串最后,而read函数读的是光标后面的内容,直接读无法读出,必须重新关闭开启文件重置光标。
列:
int n_write=write(fd,buf,strlen(buf));
if(n_write != -1){
printf("write %d byte to flie\n",n_write);
}
close(fd); // 在write函数完成后关闭重启文件重置光标,
fd=open("./file1",O_RDWR);//重新打开文件
char *readBuf;//定义一个指针用来储存read读到的内容
readBuf=(char *)malloc(sizeof(char)*n_write+1);//给指针开辟空间后就可以读出内容了
10.光标定位方法2:
SEEK_SET:光标在头部;SEEK_END:光标在尾部;SEEK_CUR光标在当前位置;
函数:off_t lseek(int fd, off_t offset, int whence); fd为目标文件的open返回值,offset为光标相对于whence位置的偏移量,whence为光标位置,上面三个。往左移动用负数右移动用正数,返回值是移动的字节数,因此也可以用lseek函数求字符串的大小。
int main()
{
int fd;
char *buf="test test!";
// int open(const char *pathname, int flags);
fd=open("./file1",O_RDWR);//用可读可写方式打开file1文件
if(fd == -1){ //判断文件打开是否成功
printf("open file1 failed\n");
//int open(const char *pathname, int flags, mode_t mode);
fd=open("./file1",O_RDWR|O_CREAT,0600);//若file1文件不存在则创建一个权限位0600的新文件并打开。
if(fd>0){
printf("create file1\n ");
}
}
printf("fd=%d\n",fd);
//ssize_t write(int fd, const void *buf, size_t count);
int n_write=write(fd,buf,strlen(buf));//将buf中的字符串写入fd文件中
if(n_write != -1){ //判断文件写入是否成功
printf("write %d byte to flie\n",n_write);
}
// close(fd);//文件写入后光标在字符串尾部,需要关闭文件重新打开重置光标才能读取出来
// fd=open("./file1",O_RDWR);
//off_t lseek(int fd, off_t offset, int whence);
// lseek(fd,0,SEEK_SET);//将光标移到字符串头相差0个字节处,重置光标
lseek(fd,-n_write,SEEK_END);//将光标向左移至与字符串尾部相差字符串长度个字节处
char *readBuf;
readBuf=(char *)malloc(sizeof(char)*n_write+1);
//ssize_t read(int fd, void *buf, size_t count);
int n_read=read(fd,readBuf,n_write);//读文件
printf("read:%d\n",n_read);
printf("%s\n",readBuf);
close(fd);
return 0;
}
11.文件创建函数:int creat(const char *pathname, mode_t mode);
pathname为要创建的文件名,可以写入路径,mode为文件的权限;包括(S-IRUSR 可读4;S-IWUSR 可写2;S-IXUSR 可执行1;S-IRWXU 可读,可写,可执行7)。
列:fd=creat("/home/CLC/file2",S_IRWXU);创建一个在clc路径下的文件file2,权限是可读可写可执行,返回值fd是文件代码,和open返回值一样。
12.文件操作原理简述:对于内核而言,所有文件的引用都由文件描述符fd引入,open和creat的返回值就是文件描述符,open的返回值是非负整数从3开始,0,1,2则是系统默认的文件描述符,0为标准输入,1为标准输出,2为标准错误。文件描述符的作用域只在当前进程,出了这个进程就失效了。
int main() //通过系统默认的文件描述符实现键盘的输入输出
{
char buf[128];
int n_read = read(0,buf,7);//0为标准输入,从0这个文件中读7个字节。
int n_write= write(1,buf,strlen(buf));//将从0中读出的buf写到标准输出1中。
printf("READ:%d,WRITE:%d\n",n_read,n_write);
return 0;
}
13.在linux中操作一个文件的过程:open函数打开文件,得到文件的描述符;对文件读写操作;最后close关闭文件。
14.文件平时在块设备的文件系统文件中,这时叫做静态文件,当用open打开时linux内核会在进程中建立一个打开文件的结构体存放打开文件的信息,内核会在进程中申请一段内存将静态文件中的内容从块设备中读取到内核内存中,这个文件就叫动态文件。
15.open打开文件后对文件的读写操作都在动态文件中进行,此时静态文件和动态文件就不同了,必须用close(fd)关闭动态文件才能使静态文件中的修改同步到静态文件中。
16.块设备读写不灵活(按块读写),而内存的读写是按字节的更方便。
17.标准c库对文件操作的引入fopen和open的区别:
1.来源:open是UNIX(包括LINUX)的系统调用函数,返回文件描述符fd,只适用于特定系统;fopen是ANSIC标准中的c语言库函数 在不同系统下调用不同API,返回值是一个指向文件结构的指针。
2.移植性:fopen是c标准函数移植性好open是UNIX系统调用,移植性有限。
3.适用范围:在linux中一些特定的情款如进程之间联系的管道文件必须用open,而fopen用来操作普通正规文件。
4.文件IO层次:open低级IO,对内核依赖高,fopen高级IO对内核依赖低。
5.缓冲区:fopen在用户态有缓冲区,因此读写文件是不需要将文件从用户态转为内核态,open没有缓冲区读写时要将用户态文件转为内核态,顺序访问文件时fopen块,随机访问时open块。
6.标准c库api:fopen fwrite fputc(写入,用for循环一个字符一个字符写) fgetc(读出) feof(判断光标是否到文件尾部,当光标不在字串尾部时返回非零负数,当到达尾部时返回非零正数。)
#include <stdio.h>
#include <string.h> //标准c库只需要写c的头文件
int main()
{
// FILE *fopen(const char *path, const char *mode);
FILE *fd;//返回值为指向文件的指针
char *str=" jia you!!";
char readBuf[128]={0};
fd=fopen("./ww.txt","w+");
//size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
//ptr 写入的字符串;
//size sizeof(char)输入的是字符串,一个字符占用一个字节;
//nmemb 表示输入几个size长度的字节,size和nmemb结合就是输入的字符串长度;
//stream fopen的返回值;
int n_write=fwrite(str,sizeof(char),30,fd);
// fwrite(str,sizeof(char)*strlen(str),1,fd);//size和nmemb两个参数的不同表示方式
fseek(fd,0,SEEK_SET);//重置光标
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
int n_read=fread(readBuf,sizeof(char),100,fd);
printf("%s\n",readBuf);
printf("n_write:%d;n_read:%d\n",n_write,n_read);
close(fd);
return 0;
}
用fopen将结构体写入文件:
#include <stdio.h>
#include <string.h>
struct Test
{
int a;
char b[20];
};
int main()
{
struct Test data[2]={{2,"cd"},{3,"bc"}};
struct Test data1[2]={0};
FILE *fd;
fd=fopen("./ww.txt","w+");
int n_write=fwrite(data,sizeof(struct Test),2,fd);
fseek(fd,0,SEEK_SET);
int n_read=fread(data1,sizeof(struct Test)*2,10,fd);
printf("%d,%s\n",data1[0].a,data1[0].b);
printf("%d,%s\n",data1[1].a,data1[1].b);
printf("n_write:%d;n_read:%d\n",n_write,n_read);
fclose(fd);
return 0;
}
用open将结构体写入文件:
struct Test
{
int n;
char c;
};
int main()
{
struct Test data2[2]={{12,'a'},{16,'b'}};
struct Test data3[2];
/* int fd;
int data=100;
int data1;
fd=open("./file",O_RDWR|O_CREAT,0600); //将一个整形数写入文件
int n_write=write(fd,&data,sizeof(int));
lseek(fd,0,SEEK_SET);
int n_read=read(fd,&data1,sizeof(int));
printf("read:%d\n",data1);
*/
int fd1=open("./file1",O_RDWR|O_CREAT|O_TRUNC|0600);
write(fd1,&data2,(sizeof(struct Test)*2));
lseek(fd1,0,SEEK_SET);
read(fd1,&data3,(sizeof(struct Test)*2));
printf("%d %c\n",data3[0].n,data3[0].c);
printf("%d %c\n",data3[1].n,data3[1].c);
// close(fd);
close(fd1);
return 0;
}
实现文件的复制cp指令:
int main(int argc,char **argv)
{
int fdSrc;
int fdDes;
int size;
char *readBuf=NULL;//过度指针
if(argc != 3){ //判断输入的参数个数是否正确
printf("error\n");
exit(-1);
}
fdSrc=open(argv[1],O_RDWR);//打开原文件
size=lseek(fdSrc,0,SEEK_END);//用lseek求出原文件大小
lseek(fdSrc,0,SEEK_SET);//重置光标
// printf("%d\n",size);
readBuf=(char *)malloc(sizeof(char)*size+8);
int n_read=read(fdSrc,readBuf,size);
fdDes=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//打开或创建目标文件夹
int n_write=write(fdDes,readBuf,strlen(readBuf));//写入
close(fdSrc);
close(fdDes);
return 0;
}
改变文件中的数据:
int main(int argc,char **argv)
{
int fdSrc;
char *buf=NULL;
if(argc != 2) {
printf("error\n");
}
fdSrc=open(argv[1],O_RDWR);
int size=lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
buf=(char *)malloc(sizeof(char)*size+8);
read(fdSrc,buf,size);
// char *strstr(const char *haystack, const char *needle);
char *p=strstr(buf,"KUANG_S=");
if(p == NULL){
printf("not found!!\n");
}
p=p+strlen("KUANG_S=");
*p='7';
lseek(fdSrc,0,SEEK_SET);
write(fdSrc,buf,strlen(buf));
close(fdSrc);
return 0;
}