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

news2024/9/24 1:20:58

用系统调用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.coloradmin.cn/o/1143563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从入门到精通Ansible Playbook,一篇就够了

Playbook 一、Host Inventory(主机清单)1.1 简介1.2 inventory 文件1.2 inventory 中的变量 二、Playbook 剧本2.1 简介2.2 Playbook的组成部分2.3 如何编写Playbook&#xff1f;2.3.1 基本格式2.3.2 语句的横向/纵向写法 三、Playbook实例和知识点补充3.1 编写yum安装nginx的p…

si24r1/nrf24l01

Si24R1 可配置为 Shutdown、 Standby、 Idle-TX、 TX 和 RX 五种工作模式。 芯片上电后为shutdown模式。此模式下不可以通过芯片收发数据&#xff0c;但MCU和芯片可以通过spi协议通信&#xff0c;更改内部寄存器的状态&#xff08;如设置 CONFIG 寄存器下的 PWR_UP 位的值为 1&…

Java练习题2020 -1

统计1到N的整数中&#xff0c;被A除余A-1的偶数的个数 输入说明&#xff1a;整数 N(N<10000), A, (A 输出说明&#xff1a;符合条件的数的个数 输入样例&#xff1a;10 3 输出样例&#xff1a;2 (说明&#xff1a;样例中符合条件的2个数是 2、8) import java.util.Scanner;p…

Java SE 学习笔记(十四)—— IO流(3)

目录 1 缓冲流1.1 缓冲流概述1.2 字节缓冲流1.3 字符缓冲流 2 转换流2.1 字符输入转换流2.1 字符输出转换流 3 序列化3.1 对象序列化3.2 对象反序列化 4 打印流5 与Properties结合使用6 IO 框架 1 缓冲流 1.1 缓冲流概述 我们之前学习的字节流、字符流属于基础流、原始流&…

引流大法,助你销量翻倍!亚马逊新卖家必备的六种流量来源!

作为亚马逊的一个新卖家&#xff0c;我们在新店上传产品之后&#xff0c;第一个目标就是引流&#xff0c;因为流量是支撑店铺销量的重要环节&#xff0c;那么我们引流的方式都有哪些呢&#xff1f; ​首先我们要知道亚马逊的一些流量来源分别有哪几块&#xff01; 一、平台自…

计算机网络重点概念整理-第五章 传输层【期末复习|考研复习】

第五章 传输层 【期末复习|考研复习】 计算机网络系列文章传送门&#xff1a; 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 第五章 传输层 【期末复习|考研复习…

通过宏定义解决编程难题

大家好&#xff0c;我们今天来通过我们的define定义宏解决C语言上的难题。 实例一&#xff1a; offsetof这个宏我们在学习结构体的时候就已经了解过了&#xff0c;这个宏是我们在计算结构体大小的时候来查看每个结构体成员的偏移量的&#xff0c;那么我们在这里就来模拟实现一…

【LeetCode:2558. 从数量最多的堆取走礼物 | 大根堆】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

面试算法43:在完全二叉树中添加节点

题目 在完全二叉树中&#xff0c;除最后一层之外其他层的节点都是满的&#xff08;第n层有2n-1个节点&#xff09;。最后一层的节点可能不满&#xff0c;该层所有的节点尽可能向左边靠拢。例如&#xff0c;图7.3中的4棵二叉树均为完全二叉树。实现数据结构CBTInserter有如下3种…

线程状态,BLOCKED和WAITING 有什么区别

BLOCKED 和 WAITING 都是属于线程的阻塞等待状态。 BLOCKED BLOCKED 状态是指线程在等待监视器锁的时候的阻塞状态。 也就是在多个线程去竞争 Synchronized 同步锁的时候&#xff0c;没有竞争到锁资源的 线程&#xff0c;会被阻塞等待&#xff0c;这个时候线程状态就是 BLOCK…

众和策略:数据要素市场腾飞在即 游戏市场持续高增长

昨日&#xff0c;两市股指早盘弱势下探&#xff0c;午后沪指在银行、电力等板块的带动下发力拉升&#xff0c;深成指、创业板指均走高。到收盘&#xff0c;沪指涨0.48%报2988.3点&#xff0c;深成指涨0.4%报9566.1点&#xff0c;创业板指涨0.65%报1875.86点&#xff1b;两市合计…

[javaweb]——spring框架之控制反转(IOC)与依赖注入(DI)

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、概念介绍 二、示例演示 2.1 代码高内聚问题 2.2 三层架构 2.3 分层解耦 2.4 分层解耦的实现 &#x1f4d5;总结 一、概念介绍 控制反转&#xff1a;简称IOC&#xff0c;对象的创建控制权由程序自身转…

vulnhub_DeRPnStiNK靶机渗透测试

VulnHub2018_DeRPnStiNK靶机 https://www.vulnhub.com/entry/derpnstink-1,221/ flag1(52E37291AEDF6A46D7D0BB8A6312F4F9F1AA4975C248C3F0E008CBA09D6E9166) flag2(a7d355b26bda6bf1196ccffead0b2cf2b81f0a9de5b4876b44407f1dc07e51e6) flag4(49dca65f362fee401292ed7ada96f9…

人工智能基础_机器学习006_有监督机器学习_正规方程的公式推导_最小二乘法_凸函数的判定---人工智能工作笔记0046

我们来看一下公式的推导这部分比较难一些, 首先要记住公式,这个公式,不用自己理解,知道怎么用就行, 比如这个(mA)T 这个转置的关系要知道 然后我们看这个符号就是求X的导数,X导数的转置除以X的导数,就得到单位矩阵, 可以看到下面也是,各种X的导数,然后计算,得到对应的矩阵结…

ADI模数转换AD7091的SPI驱动接口verilog,代码/视频

名称&#xff1a;ADI模数转换AD7091的SPI驱动 软件&#xff1a;QuartusII 语言&#xff1a;Verilog 代码功能&#xff1a; 完成ADI单通道模数转换器AD7091R的逻辑接口设计。1 MSPS、超低功耗、12-Bit ADC &#xff08;1&#xff09;实现全部逻辑接口功能&#xff0c;完成对…

云端代码编辑器Atheos

什么是 Atheos &#xff1f; Atheos是一个基于 Web 的 IDE 框架&#xff0c;占用空间小且要求最低&#xff0c;构建于 Codiad 之上&#xff0c;不过 Atheos 已从原始 Codiad 项目完全重写&#xff0c;以利用更现代的工具、更简洁的代码和更广泛的功能。 注意事项 群晖内核版本太…

系列二十、循环依赖(二)

一、请解释下Spring的三级缓存 所谓Spring的三级缓存是Spring内部解决循环依赖的三个Map&#xff0c;即DefaultSingletonBeanRegistry中的三个Map。 二、A、B两对象在三级缓存中的迁移过程 第一步&#xff1a;A创建过程中需要B&#xff0c;于是A将自己放到三级缓存里面&#x…

ubuntu安装nps客户端

Ubuntu安装nps客户端 1.什么是nps内网穿透&#xff1f;2.设备情况3.下载客户端3.链接服务端3.1、无配置文件模式3.2、注册到系统服务(启动启动、监控进程) 1.什么是nps内网穿透&#xff1f; nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发…

vue笔记(三)

15、过滤器 过滤器 用法&#xff1a;对要显示的数据进行特定格式化后再显示&#xff08;用于一个简单的逻辑处理&#xff09;语法 1、注册过滤器&#xff1a;Vue.fillter(name,callback) &#xff08;全局&#xff09;或 new Vue{filters&#xff1a;{}}&#xff08;局部&…

Ubuntu20运行SegNeXt代码提取道路水体(四)——成功解决训练与推理自己的数据集iou为0的问题!!

在我的这篇博文里Ubuntu20运行SegNeXt代码提取道路水体(三)——SegNeXt训练与推理自己的数据集 经过一系列配置后 iou算出来是0 经过多次尝试后 终于让我试出来了正确配置方法&#xff01; 具体的配置细节请查看这篇文章 1、在mmseg/datasets下面对数据集进行初始定义 我新建…