在文件指定位置插入数据而不覆盖
#include <stdio.h>
#include <string.h> //strerror
#include <errno.h> //errno
#include <unistd.h> //read write
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PER_IO_BYTES 4096
int main(int argc, char *argv[])
{
char caFile[64] = {'\0'};
strncpy(caFile, argv[1], sizeof(caFile));
int ret = -1;
strcat(caFile, ".old");
ret = rename(argv[1], caFile);
if (-1 == ret)
{
printf("rename error:%s\n", strerror(errno));
return -1;
}
int fdNew = -1;
fdNew = open(argv[1], O_WRONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fdNew)
{
printf("open error:%s\n", strerror(errno));
return -1;
}
int fdOld = -1;
fdOld = open(caFile, O_RDONLY);
if (-1 == fdOld)
{
printf("open error:%s\n", strerror(errno));
return -1;
}
off_t offset = 0;
printf("please input position:");
scanf("%ld", &offset);
char caBuf[PER_IO_BYTES] = {'\0'};
int iLeft = offset;
//将指定位置之前的数据拷贝到新文件中
while (iLeft)
{
if (iLeft >= PER_IO_BYTES)
{
ret = read(fdOld, caBuf, PER_IO_BYTES);
}
else
{
ret = read(fdOld, caBuf, iLeft);
}
if (-1 == ret)
{
printf("read error:%s\n", strerror(errno));
break;
}
iLeft -= ret;
ret = write(fdNew, caBuf, ret);
if (-1 == ret)
{
printf("write error:%s\n", strerror(errno));
break;
}
}
//在指定的位置写入数据
char *pData = "$$$qwertyuiopasdfghjklzxcvbnm$$$";
ret = write(fdNew, pData, strlen(pData));
if (-1 == ret)
{
printf("write error:%s\n", strerror(errno));
return;
}
//将指定位置之后的数据写入新文件中
while (1)
{
ret = read(fdOld, caBuf, PER_IO_BYTES);
if (-1 == ret)
{
printf("read error:%s\n", strerror(errno));
break;
}
else if (0 == ret)
{
break;
}
ret = write(fdNew, caBuf, ret);
if (-1 == ret)
{
printf("write error:%s\n", strerror(errno));
break;
}
}
close(fdNew);
close(fdOld);
ret = remove(caFile);
if (-1 == ret)
{
printf("remove error:%s\n", strerror(errno));
return -1;
}
return 0;
}
测试文件是否存在(可读可写可执行)
#include <unistd.h>
#include <stdio.h> //perror
//mode:
// F_OK:测试文件是否存在
// R_OK:测试用户是否对文件具有可读权限
// W_OK:测试用户是否对文件具有可写权限
// X_OK:测试用户是否对文件具有可执行权限
//测试用户对于指定的文件是否具有mode权限
//如果有,则函数返回0
//否则返回-1
//int access(const char *pathname, int mode);
int main(int argc, char *argv[])
{
int ret = -1;
//ret = access(argv[1], F_OK);
//ret = access(argv[1], R_OK | W_OK);
ret = access(argv[1], X_OK);
if (-1 == ret)
{
perror("access");
return -1;
}
else if (0 == ret)
{
printf("user has those permissions\n");
}
return 0;
}
判断文件类型(普通文件,目录文件)
#include <stdio.h>
#include <string.h>
/*stat()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/*opendir()*/
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
DIR *pDir = opendir(argv[1]);
if (NULL == pDir)
{
perror("opendir:");
return -1;
}
printf("opendir ok\n");
struct dirent *pDirent = NULL;
struct stat fileStat;
int ret = -1;
pDirent = readdir(pDir);
int iRegNum = 0;
int iDirNum = 0;
int iOthNum = 0;
while (NULL != pDirent)
{
printf("%s\n", pDirent->d_name);
ret = stat(pDirent->d_name, &fileStat);
if (0 == ret)
{
switch (fileStat.st_mode & S_IFMT)
{
case S_IFREG:
iRegNum++;
break;
case S_IFDIR:
iDirNum++;
break;
default:
iOthNum++;
break;
}
}
else if (-1 == ret)
{
perror("stat");
break;
}
pDirent = readdir(pDir);
}
printf("普通的文件:%d个.\n", iRegNum);
printf("目录的文件:%d个.\n", iDirNum);
printf("其他类型的文件:%d个.\n", iOthNum);
closedir(pDir);
return 0;
}
1.进程的命令
查看CPU:top
查看所有的进程:ps -A
查看当前的进程:ps
关闭进程:kill -9 进程id
创建进程:fork
父进程,子进程(fork)
#include <unistd.h> //fork()
#include <stdio.h>
#include <string.h>
int main(void)
{
pid_t pid = -1;
int iNum = 0;
char caData[32] = {'\0'};
//子进程创建后,和父进程属于两个相互独立的进程
//父进程调用fork,这是一个系统调用,因此进入内核
//内核根据父进程复制出一个子进程,父子进程的PCB信息相同
//用户态代码和数据也完全相同。
//因此,子进程现在的状态看起来和父进程一样,做完了初始化
//刚调用了fork进入内核,还没有从内核返回。
//现在有两个一模一样的进程看起来都调用了fork进入内核等待
//从内核返回(实际上fork只调用了一次)。此外系统中还有其他
//进程等待从内核返回。是父进程先返回还是子进程先返回,还是
//父子进程都等待,其他进程先返回,这是不确定的。
//取决于内核的调度算法
pid = fork();
//fork成功:将子进程的id返回给父进程的pid变量
// 将0返回给子进程的pid变量
// 失败:返回-1给父进程的pid变量,子进程不会被创建
// 并且错误号会被设置
if (pid > 0) //父进程
{
printf("this is parent process\n");
strcpy(caData, "this is parent process\n");
iNum = 3;
}
else if (0 == pid) //子进程
{
printf("this is child process\n");
strcpy(caData, "this is child process\n");
iNum = 6;
}
else if (-1 == pid) //创建进程失败
{
perror("fork");
return -1;
}
int i = 0;
for (; i < iNum; i++)
{
printf("%s", caData);
sleep(1);
}
printf("Hello World\n");
return 0;
}
僵尸进程
#include <unistd.h> //fork()
#include <stdio.h>
#include <string.h>
//一个进程结束时会关闭所有的文件描述符,
//释放在用户空间分配的内存,
//但它的PCB还保留着,
//如果进程异常终止则保留着导致该进程终止的信号
//如果正常终止则保留退出状态:在终端可以用“$?”来查看
//父进程可以调用wait或waitpid获取这些信息,
//然后彻底清楚掉这个进程
//如果一个进程终止,但是其父进程尚未调用wait或者waitpid
//对他进行清理,这时的进程状态称之为僵尸进程。
//任何进程在刚终止的时候都是僵尸进程,
//正常情况下僵尸进程会立刻被父进程清理。
//僵尸进程的危害:
// 系统允许存在的进程数是有上限的。
// 若存在大量的僵尸进程,则可能创建新的进程由于没有
// 进程号分配而失败
//形成僵尸进程实例:
int main(void)
{
pid_t pid = -1;
pid = fork();
if (pid > 0) //父进程
{
printf("this is parent process\n");
while (1)
{}
}
else if (0 == pid) //子进程
{
printf("this is child process\n");
return 0;
}
else if (-1 == pid) //创建进程失败
{
perror("fork");
return -1;
}
printf("Hello World\n");
return 0;
}
处理僵尸进程
#include <unistd.h> //fork()
#include <stdio.h>
#include <string.h>
/*waitpid()*/
#include <sys/types.h>
#include <sys/wait.h>
//僵尸进程的处理方式
//1,将子进程的善后处理交给祖宗进程(父进程不方便对子进程清理)
// A-->B-->C: 将B进程挂掉,那么C进程的清理工作由祖宗进程来做
//2,父进程自己调用相应函数来对子进程做善后处理
// 调用wait()或者waitpid()
int main(void)
{
pid_t pid = -1;
pid = fork();
if (pid > 0) //父进程
{
printf("this is parent process\n");
//阻塞等待子进程的结束
//获得子进程的退出状态,并对子进程做清理工作
wait(NULL);
while (1)
{}
}
else if (0 == pid) //子进程
{
printf("this is first child process\n");
pid_t pid2 = fork();
if (pid2 > 0)
{
return 0;
}
else if (0 == pid2)
{
int i = 0;
for (; i < 3; i++)
{
printf("this is second child process\n");
}
return 0;
}
}
else if (-1 == pid) //创建进程失败
{
perror("fork");
return -1;
}
printf("Hello World\n");
return 0;
}
网友评论