Linux C 目錄基本操作

需要引用的頭文件

#include <unistd.h>

unistd.h 為程序提供了對POSIX操作系統API的訪問接口,主要用于提供與系統調用相關的功能。

char *getcwd(char *buf, size_t size);

用于獲取當前工作目錄(Current Working Directory)的絕對路徑。

參數
buf: 指向存放當放當前目錄的數組
size: 數組的大小
返回值
成功:返回包含當前工作目錄的字符串。如果buf不為NULL,即返回buf。
失敗:返回NULL,并設置errno

示例:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {char *buf = NULL; // 使用動態分配char *cwd = getcwd(buf, 0); // 0 表示動態分配if (cwd == NULL) {perror("getcwd failed");return 1;}printf("Current working directory: %s\n", cwd);free(cwd); // 釋放動態分配的內存return 0;
}

運行該程序后,會輸出當前工作目錄的絕對路徑。

如果傳入的 buf 為 NULL ,且 size 為 0,則 getcwd 會調用 malloc 申請合適大小的內存空間,填入當前工作目錄的絕對路徑,然后返回 malloc 申請的空間的地址。
注意: getcwd 不負責 free 申請的空間, free 是調用者的職責。

int chdir(const char *path);

chdir 函數可以改變當前工作目錄。
參數
path: 改變后的路徑。?

  • 路徑可以是絕對路徑(從根目錄開始),也可以是相對路徑(相對于當前工作目錄)。

返回值
成功:返回0。
失敗:返回-1,并設置errno。

chdir 函數用于將當前進程的工作目錄切換到指定的目錄。當前工作目錄是指當前進程在文件系統中的位置,類似于在命令行中使用 cd 命令的效果。改變工作目錄后,所有相對路徑的文件操作都將基于新的工作目錄進行。

示例:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 嘗試切換到指定目錄if (chdir("/home/user/project") != 0) {perror("chdir failed");return 1;}printf("Successfully changed directory to /home/user/project\n");// 獲取當前工作目錄并打印char *buf = NULL; // 使用動態分配char *cwd = getcwd(buf, 0); // 0 表示動態分配if (cwd == NULL) {perror("getcwd failed");return 1;}printf("Current working directory: %s\n", cwd);free(cwd); // 釋放動態分配的內存return 0;
}

注意事項

  • 權限問題

    • 調用進程需要有足夠的權限才能切換到指定目錄。如果目標目錄的權限設置不允許當前用戶訪問,則會返回 EACCES 錯誤。

  • 線程安全性

    • chdir 函數是線程安全的,可以在多線程程序中安全使用。但是,需要注意的是,改變工作目錄會影響整個進程,包括所有線程。

int mkdir(const char *pathname, mode_t mode);

mkdir 函數用于創建一個新的目錄。如果指定的路徑已經存在,或者路徑中某個組件不存在或不是目錄,函數將失敗并返回相應的錯誤碼。

參數
pathname: 要創建目錄的路徑
mode: 目錄的權限位,會受文件創建掩碼umask的影響,實際的權限為(mode & ~umask
& 0777)

umask(用戶文件創建掩碼,User File Creation Mask)是一個用于控制新創建文件和目錄默認權限的機制。它通過限制文件和目錄的權限,確保新創建的文件和目錄不會被賦予過于寬松的權限。

可以通過在終端中鍵入 umask 來查看默認掩碼值

假設 umask 設置為 0022,那么:

  • 對于文件:

    最終權限=0666&~0022=0666&0755=0644

    即文件的最終權限為 0644(所有者有讀寫權限,組內用戶和其他用戶有讀權限)。

返回值
成功:返回0
失敗:返回-1,并設置errno

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>int main() {// 設置 umask 為 0022mode_t old_umask = umask(0022);// 創建目錄const char *pathname = "/home/user/newdir";mode_t mode = 0777; // 設置目錄權限為 777if (mkdir(pathname, mode) != 0) {perror("mkdir failed");return 1;}printf("Successfully created directory: %s\n", pathname);// 恢復舊的 umaskumask(old_umask);return 0;
}


int rmdir(const char *pathname);

rmdir 函數用于刪除一個空目錄。如果目錄不為空(即目錄中包含文件或其他目錄),rmdir 將無法刪除該目錄,并返回 EEXIST 錯誤。
參數
pathname: 要刪除的目錄
返回值
成功:返回0
失敗:返回-1,并設置errno

#include <func.h>
int main(int argc, char* argv[]) {// ./rmdir dirARGS_CHECK(argc, 2);int ret = rmdir(argv[1]);// 注意:rmdir 只能刪除空目錄ERROR_CHECK(ret, -1, "rmdir");return 0;
}
  • rmdir 函數用于刪除空目錄。

  • 如果目錄不為空,需要先刪除目錄中的內容,再刪除目錄。

如果該目錄非空,需要遞歸刪除目錄中的內容,實現如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>int remove_directory(const char *pathname) {DIR *dir;struct dirent *entry;char path[PATH_MAX];int ret = 0;// 打開目錄dir = opendir(pathname);if (dir == NULL) {perror("opendir failed");return -1;}// 遍歷目錄中的所有條目while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {continue; // 跳過 "." 和 ".."}// 構造完整的路徑snprintf(path, sizeof(path), "%s/%s", pathname, entry->d_name);// 檢查是否為目錄struct stat statbuf;if (stat(path, &statbuf) == -1) {perror("stat failed");ret = -1;break;}if (S_ISDIR(statbuf.st_mode)) {// 遞歸刪除子目錄if (remove_directory(path) == -1) {ret = -1;break;}} else {// 刪除文件if (unlink(path) == -1) {perror("unlink failed");ret = -1;break;}}}// 關閉目錄closedir(dir);// 刪除當前目錄if (rmdir(pathname) == -1) {perror("rmdir failed");return -1;}return ret;
}int main() {const char *pathname = "/home/user/newdir";// 嘗試刪除目錄if (remove_directory(pathname) != 0) {return 1;}printf("Successfully removed directory: %s\n", pathname);return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86009.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86009.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86009.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于二分和分治的詳細講解(從屬于GESP五級)

本章內容 二分 分治 當你把疑惑一劈為二&#xff0c;困境就只剩下一半。 一、二分查找 1. 何謂“二分”&#xff1f; “二分”本質是一種 對單調現象反復折半 的搜索思想。 單調現象&#xff1a;隨變量增大&#xff0c;目標狀態只會保持“假→真”或“真→假”一次性躍遷…

程序猿成長之路之數據挖掘篇——聚類算法介紹

作為無監督學習算法的基礎&#xff0c;學好聚類算法很關鍵&#xff0c;我之前介紹過kmeans聚類算法&#xff0c;現在系統的介紹一下聚類算法 1. 什么是分類 日常生活中我們會經常見到分類的情況&#xff0c;如家里大掃除時給物品歸類&#xff0c;超市貨架上商品分類等。分類就…

PostgreSQL 性能優化與集群部署:PGCE 認證培訓實戰指南

&#xff5c;深夜被數據庫報警驚醒&#xff1f; &#xff5c;海量數據查詢卡死業務&#xff1f; &#xff5c;主庫宕機導致服務中斷&#xff1f; 如果你正被這些PostgreSQL生產難題困擾&#xff0c;是時候系統掌握數據庫內核優化與高可用架構了&#xff01;深度求索聯合PG分會…

Java 對象映射 數據庫表映射 工具類 兩個對象/表實現映射轉換

場景&#xff1a;需要將一個對象的各個字段中的數據映射到另一個對象的字段數據中&#xff0c;或將一個數據庫表映射到另一張表中。 本文使用泛型編程實現了一個對象映射功能的工具類。 需要源對象&#xff0c;映射關系map&#xff0c;目標類。由于是動態的類&#xff0c;所以…

Linux離線搭建Jenkins

Linux離線搭建Jenkins(centos7) Jenkins簡介: Jenkins只是一個平臺&#xff0c;真正運作的都是插件。這就是jenkins流行的原因&#xff0c;因為jenkins什么插件都有&#xff0c;Hudson是Jenkins的前身&#xff0c;是基于Java開發的一種持續集成工具&#xff0c;用于監控程序重…

從零學習linux(2)——管理

一.用戶管理 1.用戶屬性 用戶名、口令、用戶ID&#xff08;UID&#xff09;、用戶主目錄&#xff08;HOME&#xff09;、用戶shell 2. 3. 4.adduser添加用戶 語法&#xff1a;adduser 用戶名 如# adduser superw 添加用戶名為superw的新用戶 5.deluser刪除用戶 語法&am…

《貴州棒壘球》有什么國家級比賽·棒球1號位

中國國家級棒球比賽盤點 | 小白入門指南 3月 | 中國棒球聯賽 (China Baseball League) 國內最高水平職業聯賽&#xff0c;各省市職業隊角逐冠軍&#xff01; 英文&#xff1a;Top-tier professional event with teams nationwide. 5月 | 全國青年棒球錦標賽 (National Youth …

該項目名為“EduPal“,AI推薦

## 完整代碼實現 ### 后端代碼 (app.py) python import os import json import uuid import requests from datetime import datetime from flask import Flask, render_template, request, jsonify from dotenv import load_dotenv # 加載環境變量 load_dotenv() app …

C++法則15:匹配失敗并不是一種錯誤(Substitution Failure Is Not An Error)。

C法則15&#xff1a;匹配失敗并不是一種錯誤(Substitution Failure Is Not An Error)。 應用例子&#xff1a; SFINAE &#xff1a;關于is_class&#xff0c;is_base_of&#xff0c;C編譯器的魔法器&#xff0c;如何實現&#xff0c;is_class&#xff0c;is_base_of。_c is cl…

Ollama客戶端 + Docker搭建本地知識庫(Mac系統)

一、環境準備 1. 安裝Ollama客戶端 官網下載&#xff1a;https://ollama.com 驗證安裝&#xff1a; ollama --version2. 安裝Docker Desktop 下載地址&#xff1a;https://www.docker.com/products/docker-desktop 安裝后確保Docker狀態為"Running" 二、基礎搭建…

FastMCP 2.9 版本詳解:MCP 原生中間件與類型轉換增強

下面我將從三個方面來講解這個&#xff0c;第一是講解2.9版本的更新&#xff0c;第二是講解什么將手動解析底層JSON-RPC 消息&#xff0c;丟失 FastMCP 高層語義&#xff0c;第三是講一講&#xff0c;什么叫做中間件。不了解的兄弟們系好安全帶&#xff0c;我們準備發車了&…

LTspice仿真6——PWL折線波產生

1.自定義波形 2.自定義波形周期 3.以文件.txt的形式定義折線波 4.通過C語言編程&#xff0c;一系列操作&#xff0c;生成自定義正弦波&#xff08;可自定義性強&#xff09;

FunASR搭建語音識別服務和VAD檢測

調整VAD參數 1. 查找VAD模型的配置文件 FunASR中的VAD模型為FSMN-VAD&#xff0c;參數配置類為VADXOptions&#xff0c;可以在以下路徑中找到&#xff1a; /workspace/FunASR/runtime/python/onnxruntime/funasr_onnx/utils/e2e_vad.py 其中&#xff0c;VADXOptions類定義了…

多模態大模型(從0到1)

文章目錄 一、多模態大模型二、常見模態組合 典型應用場景三、多模態&#xff08;模型 框架&#xff09;1. 多模態模型2. 多模態框架 —— 開源項目推薦&#xff08;可快速上手&#xff09; 四、入門與學習路線1. 理論基礎2. 主流多模態模型實戰3. 進階與應用拓展&#x1f4d…

# Vue.js 精確輪播組件實現詳解

## &#x1f4d6; 概述 本文詳細介紹了一個基于 Vue.js 開發的高精度輪播組件&#xff0c;該組件實現了精確的卡片對齊和平滑滾動效果。組件支持混合布局&#xff08;大卡片網格布局&#xff09;&#xff0c;具備智能位置計算和精確滾動控制功能。 ## ? 組件特點 ### &#x1…

將RESP.app的備份數據轉碼成AnotherRedisDesktopManager的格式

將RESP.app的備份數據轉碼成AnotherRedisDesktopManager的格式 最近發現了AnotherRedisDesktopManager&#xff0c;這個軟件可以直接展示proto數據。 將RESP.app導出的json文件&#xff0c;轉碼為AnotherRedisDesktopManager的ano文件&#xff08;是一個list轉了base64&#xf…

前端基礎知識JavaScript系列 - 09(JavaScript原型,原型鏈 )

一、原型 JavaScript 常被描述為一種基于原型的語言——每個對象擁有一個原型對象 當試圖訪問一個對象的屬性時&#xff0c;它不僅僅在該對象上搜尋&#xff0c;還會搜尋該對象的原型&#xff0c;以及該對象的原型的原型&#xff0c;依次層層向上搜索&#xff0c;直到找到一個…

vue3+ts 使用VueCropper實現剪切圖片

效果圖&#xff1a; 參考文檔&#xff1a; Vue-Cropper 文檔Vue-Cropper 文檔 安裝VueCropper //npm安裝 npm install vue-croppernext -d --save//yarn安裝 yarn add vue-croppernext 引入組件 在main.ts中全局注冊&#xff1a; import VueCropper from vue-cropper; i…

el-table特殊表頭樣式

el-table特殊表頭樣式 實現表頭是按鈕 <el-table-column align"center"><template slot"header"><el-buttonsize"mini"type"primary"icon"el-icon-plus"circleclick"addData"></el-button&g…

el-tree的屬性render-content自定義樣式不生效

需求是想要自定義展示el-tree的項&#xff0c;官網有一個:render-content屬性&#xff0c;用的時候發現不管是使用class還是style&#xff0c;樣式都沒有生效&#xff0c;還會報一個錯&#xff0c;怎么個事呢&#xff0c;后來發現控制臺還會報一個錯“vue.js:5129 [Vue warn]: …