Linux文件系统实验(C语言实现新建、打开、关闭、读写文件以及查改文件权限)

2023-11-18

操作系统实验导航
实验一:银行家算法 https://blog.csdn.net/weixin_46291251/article/details/115384510
实验二:多级队列调度和多级反馈队列调度算法 https://blog.csdn.net/weixin_46291251/article/details/115530582
实验三:动态分区式内存管理 https://blog.csdn.net/weixin_46291251/article/details/115772341
实验四:Linux下多进程通信 https://blog.csdn.net/weixin_46291251/article/details/116274665
实验五:进程通信的三种方式 https://blog.csdn.net/weixin_46291251/article/details/116301250
实验六:Linux文件系统实验 https://blog.csdn.net/weixin_46291251/article/details/116423798
实验七:自制简单U盘引导程序 https://blog.csdn.net/weixin_46291251/article/details/116427629
实验八:磁盘调度算法 https://blog.csdn.net/weixin_46291251/article/details/116431907
实验九:请求分页系统中的置换算法 https://blog.csdn.net/weixin_46291251/article/details/116443021
学习笔记:操作系统复习笔记 https://blog.csdn.net/weixin_46291251/article/details/117086851

题目描述:

使用文件系统调用编写一个文件工具 filetools,使其具有以下功能:

  • 1.创建新文件
  • 2.写文件
  • 3.读文件
  • 4.修改文件权限
  • 5.查看当前文件权限
  • 0.退出
  • 提示用户输入功能号,并根据用户输入的功能选择相应的功能。

文件按可变记录文件组织,具体记录内容自行设计。

算法设计:

打开/新建文件(open)

调用open可以打开或创建一个文件。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int oflag, ... /* mode_t mode */);

返回若成功为文件描述符,若出错为- 1
参数:
第一个参数**pathname*是要打开或创建的文件的名字。
第二个参数oflag参数可用来说明此函数的多个选择项。用下列一个或多个常数进行或运算构成oflag*参数(这些常数定义在< fcntl . h >头文件中, 在这三个常数中应当只指定一个):

O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读、写打开

第三个可选参数:

O_APPEND 每次写时都加到文件的尾端。
O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位。
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错。这可测试一个文件是否存在。
O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。
O_NONBLOCK 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I /
O操作设置非阻塞方式。
O_SYNC 使每次write都等到物理I / O操作完成。

读文件(read)

#include <unistd.h>
ssize_t read(int fd, void *buff, size_t nbytes) ;

返回:读到的字节数,若已到文件尾为0,若出错为-1

写文件(write)

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes) ;
  • 返回:若成功为已写的字节数,若出错为-1
  • 对于普通文件,写操作从文件的当前位移量处开始。如果在打开该文件时,指定了O_APPEND选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处。在一次成功写之后,该文件位移量增加实际写的字节数。

查权限

char* pargv[4]={"ls","-l","file1",NULL};
 显示文件权限 execv("/bin/ls",pargv); 
 
  • 所以查询文件权限只需要:
    1.pargv[2]改为待操作的文件名
    2.执行execv("/bin/ls",pargv);

由于进程执行完execv后会退出而无法执行其他逻辑,于是fork一个子进程来作查权限的操作,主进程调用wait等子进程结束即可。

int p =fork();
            if(p==0)
                check_file_mod();
            else
                wait(NULL);       

改权限chmod

  • linux下的文件权限分三级:owner,group,others三类。每类占权限位的三位。
  • r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
  • 其中:r=4,w=2,x=1
    例如:若要rwx属性则4+2+1=7;
    若要rw-属性则4+2=6;
    若要r-x属性则4+1=7。
  • 常见权限:

-rw------- (600) – 只有属主有读写权限。
-rw-r–r-- (644) – 只有属主有读写权限;而属组用户和其他用户只有读权限。
-rwx------ (700) – 只有属主有读、写、执行权限。
-rwxr-xr-x (755) – 属主有读、写、执行权限;而属组用户和其他用户只有读、执行权限。
-rwx–x--x (711) – 属主有读、写、执行权限;而属组用户和其他用户只有执行权限。
-rw-rw-rw- (666) – 所有用户都有文件读、写权限。这种做法不可取。
-rwxrwxrwx (777) – 所有用户都有读、写、执行权限。更不可取的做法。

lseek调用

每个打开的文件都有一个与其相关联的“当前文件位移量”。它是一个非负整数,用以度量从文件开始处计算的字节数。通常,读、写操作都从当前文件位移量处开始,并使位移量增加所读或写的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence) ;

参数offset 的解释与参数whence的值有关

若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset 个字节

若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset, offset可为正或负

若whence是SEEK_END,则将该文件的位移量设置为文件长度加offset, offset可为正或负

具体代码:

/*
1.
open 	打开文件
creat 	创建新文件
close 	关闭文件描述字
read 	读文件
write 	写文件
*/

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

int C_fd;           //文件描述符
char filename[100]; //文件名
int isopen = 0;     //打开状态
char *pargv[4] = {"ls", "-l", NULL, NULL};

void Open_Creat_file()
{
    printf("请输入要打开/创建的文件名: ");
    scanf("%s", filename);
    C_fd = open(filename, O_RDWR, 0666);
    if (C_fd >= 0)
    {
        isopen = 1, printf("%s已存在,打开成功\n", filename);
        pargv[2] = (char *)malloc(50);
        strcpy(pargv[2], filename);
    }
    else
    {
        C_fd = open(filename, O_CREAT, 0666);
        if (C_fd >= 0)
            isopen = 1, printf("%s不存在,新建成功\n", filename);
        else
            isopen = 0, printf("打开/新建%s失败\n", filename);
    }
    //close(fd);
}
void read_file()
{
    if (!isopen)
    {
        printf("没有打开的文件,请先打开一个文件\n");
        return;
    }
    else
        printf("当前处理的文件是:%s\n", filename);
    char buffer[100];

    lseek(C_fd, 0, SEEK_SET); //从头开始读
    int t = read(C_fd, buffer, 1024);
    if (t != -1)
        printf("文件内容为:%s\n", buffer);
    else
        printf("读取失败\n");
}
void write_file()
{
    if (!isopen)
    {
        printf("没有打开的文件,请先打开一个文件\n");
        return;
    }
    else
        printf("当前处理的文件是:%s\n", filename);
    char buffer[1024];
    printf("请输入待写入内容:\n");
    scanf("%s", buffer);

    int t = write(C_fd, buffer, strlen(buffer));
    if (t == -1)
        printf("写入失败!\n");
    else
        printf("写入成功!\n");
}
void change_file_mod()
{
    if (!isopen)
    {
        printf("没有打开的文件,请先打开一个文件\n");
        return;
    }
    else
        printf("当前处理的文件是:%s\n", filename);
    int new_mode;
    printf("输入新的模式(十进制)");
    scanf("%d", &new_mode);
    int mode_u = new_mode / 100;
    int mode_g = new_mode / 10 % 10;
    int mode_o = new_mode % 10;
    new_mode = (mode_u * 8 * 8) + (mode_g * 8) + mode_o; //八进制转换
    int t = chmod(filename, new_mode);
    if (t == -1)
        printf("改变模式失败!\n");
    else{
        printf("成功改变模式!\n");
        printf("新模式:%d\n",new_mode);               
    }
}
void check_file_mod()
{
    if (!isopen)
    {
        printf("没有打开的文件,请先打开一个文件\n");
        return;
    }
    else
        printf("当前处理的文件是:%s\n", filename);
    printf("文件权限为");
    int t = execv("/bin/ls", pargv);
    if (t == -1)
        printf("查看失败\n");
}
int main()
{

    printf("-----------------CC_File_Tools--------------\n");
    printf("1.打开(不存在则新建)       2.写文件       3.读文件  \n");
    printf("4.改权限     5.查权限       0.退出    \n");
    //printf("------------------------------------\n");

    int choice = -1;
    while (1)
    {
        printf("-------------请输入选择:-----------\n");
        scanf("%d", &choice);
        switch (choice)
        {
        case 0:
        {
            printf("\n\t感谢使用!\n\n");
            return 0;
        }
        case 1:
        {
            Open_Creat_file();
            break;
        }
        case 2:
        {
            write_file();
            break;
        }
        case 3:
        {
            read_file();
            break;
        }
        case 4:
        {
            change_file_mod();
            break;
        }
        case 5:
        {
            int p =fork();
            if(p==0)
                check_file_mod();
            else
                wait(NULL);            
            break;
        }
        default:
        {
            printf("您的输入有误,请重新输入!!!\n");
        }
        }
    }

    return 0;
}

运行结果:

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux文件系统实验(C语言实现新建、打开、关闭、读写文件以及查改文件权限) 的相关文章

  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 具有少量父设备属性的 udev 规则

    我需要复杂且通用的udev规则来确定插入任何 USB 集线器的特定端口的 USB 设备 所以 我必须结合设备树不同层的父属性 我有这个 udevadm info query all name dev ttyUSB0 attribute wa
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • 如何在 Linux 主机上的 docker 容器中挂载目录 [重复]

    这个问题在这里已经有答案了 我想将一个目录从 docker 容器挂载到本地文件系统 该目录是网站根目录 我需要能够使用任何编辑器在本地计算机上编辑它 我知道我可以跑docker run v local path container path
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • python:numpy 运行脚本两次

    当我将 numpy 导入到 python 脚本中时 该脚本会执行两次 有人可以告诉我如何阻止这种情况 因为我的脚本中的所有内容都需要两倍的时间 这是一个例子 usr bin python2 from numpy import print t
  • touch命令在一个目录下创建多个文件(不同名称)

    我想制作一个在 bash 中创建目录和文件结构的脚本 我尝试过这样的事情 mkdir p 1 2 touch 1 2 a b c a b c 应该是在一个命令或其他命令中创建的文件 但由于某种原因 结构是这样的 current folder
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • 伊迪德信息

    重新定义问题 有什么方法可以获取所连接显示器的序列号吗 我想收集显示器的Eid信息 当我使用 logverbose 选项运行 X 时 我可以从 xorg 0 log 文件中获取它 但问题是 如果我切换显示器 拔出当前显示器 然后插入另一个显
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • 在主目录中安装库

    在 Linux Ubuntu 中 我尝试运行一个工具 但它显示错误 库丢失 我无权在系统中安装任何内容 或者根本无法从我的用户帐户执行 sudo 是否可以在我的主目录 没有 sudo 中安装缺少的库 在我的例子中为 libstdc so 6
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复

随机推荐

  • 5.19 华为算法笔试经验

    华为机试一共三道题 对应的分值分别为100分 200分 300分 下面介绍这次笔试题目 第一题 一共有N个员工围成一个圆圈 分别是1 2 N每一个员工身上有对应数量的令牌 轮流从顺时针以及逆时针进行报数 顺时针报数周期为R 逆时针报数周期为
  • 僵尸进程的多种处理方式-图文详细教程

    问题引起原因 yum更新导致无法使用yum 于是将占用进程kill掉 导致 ps A ostat ppid pid cmd grep e Zz ps ef no headers k8s环境kubelet服务异常 systemd1服务超时 导
  • IP地址和子网掩码详解

    原文链接 IP和子网掩码 我们都知道 是由四段数字组成 在此 我们先来了解一下3类常用的 A类IP段 0 0 0 0 到127 255 255 255 B类IP段 128 0 0 0 到191 255 255 255 C类IP段 192 0
  • Android Studio连接Mysql数据库步骤以及常见错误

    1 先把Mysql给下好 环境变量也配置好 这里我就不说了 2 下载好Navicat for Mysql软件 管理数据库 3 进入Android Studio创建一个类 写好连接数据库的代码 我们采用的是常用的JDBC方法来连接 需要的ja
  • JNI基础

    问题1 JNI是什么 答 JNI是Java语言的机制 Java可以通过JNI调用C C 代码 C C 代码也可以通过JNI调用Java代码 问题2 NDK是什么 答 NDK是代码库 功能有两个 1 将 c cpp文件转换成 so文件 2 将
  • 【产品笔记】3.产品经理实战

    1 团队合作 2 产品设计到立项 3 项目启动到产品上线 4 产品上线后的运营 产品 商业模式 功能 设计 技术 内容 产品的成功归功于整个团队的精诚合作 产品的失败只归咎于产品负责人 用户运营 拉新 留存 老用户召回 内容运营 内容质量
  • Visual Studio 2017下载地址和安装教程(图解版)

    Visual Studio 2017下载地址和安装教程 图解版 Visual Studio 2017不仅支持C C Python Visual Basic Node js HTML JavaScript等各大编程语言 还能开发 iOS An
  • 华为OD机试真题-日志排序-2023年OD统一考试(B卷)

    华为OD机试2023年最新题库 JAVA Python C 题目描述 运维工程师采集到某产品现网运行一天产生的日志N条 现需根据日志时间按时间先后顺序对日志进行排序 日志时间格式为 H M S N H表示小时 0 23 M表示分钟 0 59
  • MOS管的知识,看这一篇就可以了

    转载 21ic电子网 2020 11 15 18 19 以下文章来源于记得诚电子设计 作者记得诚 记得诚电子设计 分享电子硬件知识 永远相信美好的事情即将发生 今天的文章简单总结一下MOS管 如下是本文目录 场效应管分类 场效应管分为结型
  • 虚拟机执行子程序-虚拟机字节码执行引擎

    代码编译的结果从本地机器码转变为字节码 是存储格式发展的一小步 却是编程语言发展的一 大步 虚拟机执行子程序 虚拟机字节码执行引擎 一 概述 二 运行时栈帧结构 1 局部变量表 2 操作数栈 3 动态连接 4 方法返回地址 5 附加信息 三
  • 图像处理知识框架

    转自https blog csdn net hitwengqi article details 8292675 花了点时间整理了一下数字图像处理知识体系 从宏观上把握图像处理 使自己的学习思路就更加清晰 1 本文大部分内容来自 http b
  • Vue前端框架12 组件生命周期、生命周期的应用、动态组件、组件保持存活、异步组件、依赖注入、Vue应用原理

    文章目录 一 组件生命周期 二 生命周期的应用 三 动态组件 四 组件保持存活 五 异步组件 六 依赖注入 七 Vue应用 一 组件生命周期 每个Vue组件在创建时需要经历一系列的初始化步骤 比如设置侦听 编译模板 挂载实例到DOM 或者数
  • Matlab中的矩阵合并操作

    Matlab中的矩阵合并操作 矩阵是Matlab中最常用的数据结构之一 矩阵合并也是一个十分实用的操作 本文将介绍在Matlab中如何进行矩阵合并 并提供相应的源代码 在Matlab中 可以用方括号 来表示一个矩阵 矩阵合并可以分为横向合并
  • 【iOS】push与present Controller的区别

    文章目录 前言 一 push方法 二 pop方法 三 present方法 四 dismiss方法 五 dismiss多级的方法 举例 动画 前言 iOS推出与退出界面有两种方式 push与present 接下来笔者分别介绍这两种方式 一 p
  • Lcd(一)显示原理

    一 LCD控制原理 S5PV210处理器中自带LCD控制器 控制LCD的显示 把 LCD 图像数据从一个位于系统内存的 video buffer 传送到一个外部的 LCD 驱动器接口 类型 1 STN 超扭曲向列 它的特点是功耗低 但亮度不
  • 图片隐写神器Stegsolve安装教程

    首先需要配置电脑的java环境 网上有教程 通过该链接 www caesum com handbook Stegsolve jar 下载Stegsolve jar 有Java环境的话会自动选择使用Java打开 如下图 功能分析 File F
  • 【Bitlocker篇】BitLocker无法加密系统盘,提示正在启动Bitlocker,系统找不到指定的文件的解决方案

    Bitlocker篇 BitLocker无法加密系统盘 提示正在启动Bitlocker 系统找不到指定的文件的解决方案 先排除先天不足因素 1 首先电脑硬件支持TPM 2 电脑系统支持BitLocker加密 3 除系统盘外其他盘能正常启用B
  • 硬件产品经理:从入门到精通(新书发布)

    目录 简介 新书 框架内容 相关课程 简介 在完成多款硬件产品从设计到推向市场的过程后 笔者于2020年开始在产品领域平台输出硬件相关的内容 在这个过程中经常会收到很多读者的留言 希望能推荐一些硬件相关的书籍或资料 其实 笔者刚开始做硬件产
  • Win10 警告-已计划将多个默认网关用于提供单一网络例如Intranet或Internet)的冗余…的解决方案

    电脑因为硬盘故障更换了硬盘重新安装了系统 按照以前设置的IP地址重新设置 但是总是出现 警告 已计划将多个默认网关用于提供单一网络 折腾了好久 不得其解 最后 把 控制面板 网络和 Internet 网络连接 里的 WLAN 蓝牙网络连接
  • Linux文件系统实验(C语言实现新建、打开、关闭、读写文件以及查改文件权限)

    操作系统实验导航 实验一 银行家算法 https blog csdn net weixin 46291251 article details 115384510 实验二 多级队列调度和多级反馈队列调度算法 https blog csdn n