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

Linux 系统调用IO口,利用光标偏移实现文件复制

用系统调用IO函数实现从一个文件读取最后2KB数据并复制到另一个文件中,源文件以只读方式打开,目标文件以只写的方式打开,若目标文件不存在,可以创建并设置初始值为0664,写出相应代码,要对出错情况有一定的处理,并能够让用户自行输入要复制的文件名。

IO口即指Input和Outpot,常用的IO函数open() , close() , read() , write() ,lseek()。本节也围绕以上函数完成。

题目分析:

本质:从一个文件读取,然后写到另一个文件里。

添加形容:

源文件(要读取的文件),目标文件(要写入的文件)

源文件以只读方式打开:from_writed=open(argv[1],O_RDONLY);

目标文件以只写方式打开:to_readed=open(argv[2],O_WRONLY);

若目标文件不存在可以创建并设置初始值为0664:to_readed=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664);

命令简介:

O_RDONLY --以只读命令打开文件

O_WRONLY--以只写命令打开文件

O_WRONLY--以读写命令打开文件

O_CREAT--若文件不存在则创建

O_TRUNC--若文件存在则清除原有数据

最后一个参数mode 是文件权限,0代表没有权限,1代表可执行权限,2代表可写权限,4代表可读权限,将其相加可得0~7的八进制数。

0664表示的是 文件所有者可读可写,和文件所有者同组用户可读可写,其他用户可读。

对出错情况有一定的处理:

if(xx<0)

{

  printf("can't open %s",argv[x]);
  return-1

}

或者

if(xx<0)
{
  perror("xx");
 }

(要使用perror(),前提引用库函数 #include<error.h>

让用户自行输入要复制的文件名:

这里主函数里写入参数

int main(int argc, char *argv[])

argc用来传参,此篇argc一共有三个参数,除了程序名还有两个,分别是源文件和目标文件(“要被复制的文件”和“要复制到的文件”),基于此实现用户自行输入要复制的文件名。

 读取源文件最后2kb的数据:

用lseek()函数实现

int len;

len=lseek(from_writed,-70,SEEK_END);

题目要求是最后2kb,但是2048太大了,我写的文件比较小,我就偏移个最后70,刚好是我文件最后一句话。

大家自己看,想偏多少都行。

函数原型

off_t lseek(int fd , off_t offset, int whence)

先来说一下这个off_t类型吧,它用于指示文件的偏移量。你可以就简单的理解为这是一个64位的整形数,相当于long long int,其定义在unistd.h头文件中可以查看。

参数:fd //文件描述符,可以通过open函数得到,通过这个fd可以操作某个文件
参数: offset //文件偏移量,是一个整形数
参数:whence //偏移类型,下列三个值中选一个。

offset:

     offset > 0 向后偏移

     offset < 0 向前偏移

whence :
     SEEK_SET:从文件头开始偏移
     SEEK_CUR:从当前位置开始偏移
     SEEK_END:从文件尾开始偏移

在使用这个函数之前,我们需要往C/C++文件中导入这些头文件:

#include <sys/types.h>
#include <unistd.h>

 到此题目就分析完了。

写代码

先创个源文件

vi LLL

IO实现文件全部复制

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <error.h>
int main(int argc, char *argv[])
{
    if(argc != 3)
 {
    printf("Input error\n");
    exit(1);
 }
    int fp_from = open(argv[1], O_RDONLY);//只读
    if(fp_from==-1)
    {
        printf("open %s error\n",argv[1]);
        exit(2);
    }
    int fp_to = open(argv[2], O_WRONLY | O_CREAT, 0644);//读写,不存在则创建
    if(fp_to==-1)
    {
        printf("open %s error\n",argv[2]);
        exit(3);
    }
    int buf[1024] = {0};
    ssize_t ret;
    while(1)
   {
       ret = read(fp_from,buf,sizeof(buf) - 1);//从源文件读

       if(ret == -1)
      {
            perror("read");
      }
      else if(ret == 0)
      {
            printf("拷贝完毕\n");
            break;
      }
      ret == write(fp_to,buf,ret); //向目标文件写
      if(ret == -1)
     {
            perror("write");
     }
   }
 close(fp_from);
 close(fp_to);
    return 0;
}
                                                                                                                                                                                       

运行结果:

利用光标偏移,IO实现文件部分复制

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char **argv)
{       int from_writed;  //源文件
        int to_readed;    //目标文件
        int l_writed;     //写入长度
        int l_readed;     //读取长度
        int buf[2048];
        int len;         //偏移长度
        if(argc != 3)
        {
                printf("Input error\n");
                return -1;
        }
       from_writed=open(argv[1],O_RDONLY);//以只读方式打开源文件
       if(from_writed<=0)
        {
                 printf("can't oppen %s\n",argv[1]);
                return -1;
        }
        to_readed=open(argv[2],O_WRONLY);//以只写方式打开目标文件
        if(to_readed<=0)  //如果文件不存在
        {
                to_readed=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664);
                                            //读写方式|不存在则创建|存在则清除数据,权限0664
 
               if(to_readed<=0)
                {
                        printf("can't open %s\n",argv[2]);
                        return -1;
                }
        }
        while(1)
        {
               //     off_t len;

                len=lseek(from_writed,-70,SEEK_END); //移动光标至文件末尾前70个数据
                if(len>0)
                {
                        printf("current off_t : %d\n",len);输出当前光标位置所在
                }

                l_readed=read(from_writed,buf,2048);    //从源文件读取
                if(l_readed<0)
               {
                        printf("can't read from %s\n",argv[1]);
                        return -1;
                }
                if(l_readed>0)
                {
                        l_writed=write(to_readed,buf,l_readed);//写入到目标文件
                        if(l_writed>0)
                        {
                                printf("拷贝完毕\n");
                                break;
                        }
                        if(l_writed<0)
                        {
                                printf("can't write to %s\n",argv[2]);
                                return -1;
                        }
                }
                else
                break;
        }
        close(from_writed);
        close(to_readed);
        return 0;

}

                                                                           

还利用上面那个LLL文件

运行:

查看:

刚好偏移最后一句话。


http://www.kler.cn/a/107062.html

相关文章:

  • win32 / WTL 开发多线程应用,子线程传递大对象给UI线程(主窗口)的方法
  • 鸿蒙next版开发:相机开发-元数据(ArkTS)
  • C# 委托与匿名方法
  • 数据结构与算法-前缀和数组
  • 【深圳大学】数据结构A+攻略(计软版)
  • 知识库管理系统:企业数字化转型的加速器
  • Kotlin 使用@BindingAdapter编译出错
  • 【微服务开篇-RestTemplate服务调用、Eureka注册中心、Nacos注册中心】
  • VPS是什么?详解亚马逊云科技Amazon Lightsail(VPS)虚拟专用服务器
  • C++模拟实现-----日期计算器(超详细解析,小白一看就会!)
  • Java架构师内功计算机网络
  • LVS集群-DR模式【部署高可用LVS-DR集群】
  • Java SE 学习笔记(十四)—— IO流(3)
  • Java 反射机制详解
  • SQL server中:常见问题汇总(如:修改表时不允许修改表结构、将截断字符串或二进制数据等)
  • 【计算机网络】HTTPS 的加密流程
  • linux--
  • 简易但很实用的javaswing/gui音乐播放器
  • vscode C++项目相对路径的问题
  • Redis快速上手篇(六)主从复制
  • myTracks for Mac:GPS轨迹记录器的强大与便捷
  • 【QT开发(14)】QT P2P chat 聊天
  • k8s之Flannel网络插件安装提示forbidden无权限
  • 取Dataset子集(pytorch)
  • 52.MongoDB复制(副本)集实战及其原理分析
  • 电脑技巧:Win10飞行模式相关知识介绍