linux学习进展 文件操作
在Linux系统中,“一切皆文件”是最核心的设计理念之一——无论是普通文本文件、图片、视频,还是硬件设备(如键盘、磁盘)、进程间通信的管道、网络套接字,都被抽象为文件来统一管理。文件操作是Linux学习的基础,也是日常开发、运维中最频繁的操作,从简单的文件创建、删除,到复杂的文件读写、权限管理,都离不开文件操作的核心逻辑。本节课将全面讲解Linux文件操作,涵盖基础文件概念、常用命令实操、文件权限、系统调用(C语言),结合之前学的进程、引用计数等知识,帮大家彻底掌握Linux文件操作的精髓。
一、Linux文件核心概念(必懂)
在学习文件操作前,需先明确Linux文件的核心属性和分类,这是理解后续操作的基础,也是区别于Windows文件系统的关键。
(一)文件的核心属性
每个Linux文件都有一套完整的属性,可通过ls -l命令查看,核心属性包括以下5点,也是文件操作中需重点关注的内容:
文件类型:Linux文件分为5类,用首字符标识(
ls -l输出的第一列):-:普通文件(文本、图片、可执行程序等,最常用);
d:目录文件(文件夹,本质是包含其他文件的索引);
l:软链接文件(快捷方式,指向另一个文件/目录);
c:字符设备文件(如键盘、鼠标,按字符读写);
b:块设备文件(如磁盘、U盘,按块读写)。
文件权限:分为读(r)、写(w)、执行(x),分别对应所有者、所属组、其他用户三类权限(后续详细讲解)。
引用计数(链接数):对应
ls -l输出的第二列,记录当前有多少个“链接”指向该文件(结合之前学的refcount,本质是文件的“使用人数”),硬链接会增加引用计数,软链接不会。所有者(uid)和所属组(gid):对应
ls -l输出的第三、四列,决定了谁能对文件进行操作。文件大小和修改时间:文件大小(字节)、最后修改时间(mtime)、最后访问时间(atime)、最后状态修改时间(ctime)。
(二)文件路径
Linux文件系统是树形结构,根目录为/,每个文件/目录都有唯一的路径,分为两种:
绝对路径:从根目录
/开始,完整的路径,如/home/user/test.txt,无论当前所在目录,绝对路径都能准确定位文件;相对路径:从当前所在目录开始,如当前在
/home/user,则test.txt、./doc/file(.表示当前目录)、../test(..表示上级目录)都是相对路径。
核心技巧:使用pwd命令查看当前所在绝对路径;使用cd命令切换目录(如cd /home切换到根目录下的home目录,cd ..切换到上级目录)。
(三)硬链接与软链接(补充)
链接是Linux中实现文件共享的重要方式,分为硬链接和软链接,核心区别与引用计数相关:
硬链接(hard link):给文件创建一个新的文件名,与原文件指向同一个inode(文件的索引节点,存储文件属性和数据位置),会增加文件的引用计数。删除原文件,硬链接仍能正常访问文件数据;只有当所有硬链接都被删除(引用计数为0),文件数据才会被释放。
软链接(symbolic link,软链接):相当于Windows的快捷方式,仅记录原文件的路径,不会增加引用计数。删除原文件,软链接会失效(显示为红色闪烁),无法访问文件数据。
示例:创建硬链接和软链接(后续命令实操会详细演示):
ln test.txt hard_link.txt # 创建硬链接 ln -s test.txt soft_link.txt # 创建软链接二、Linux文件操作常用命令(实操重点)
文件操作命令是日常使用的核心,以下按“创建-查看-修改-删除-移动/复制-权限管理”的逻辑分类,每个命令给出常用选项和实操示例,可直接在Linux环境中练习。
(一)文件/目录创建:touch、mkdir
touch:创建普通文件,若文件已存在,更新文件的修改时间。touch test.txt # 创建单个普通文件touch file1.txt file2.txt # 创建多个文件touch -d "2026-04-14" test.txt # 修改文件的修改时间为指定日期mkdir:创建目录,常用选项-p(递归创建多级目录,避免报错)。mkdir doc # 创建单个目录mkdir -p doc/test/log # 递归创建多级目录(doc下的test,test下的log)
(二)文件/目录查看:ls、cat、more、less、head、tail
这类命令用于查看文件内容或目录结构,覆盖不同场景(查看目录、查看文件、查看部分内容)。
ls:查看目录下的文件/目录,最常用命令。ls # 查看当前目录下的文件/目录(简洁版)ls -l # 查看详细信息(权限、引用计数、所有者、大小、时间等)ls -a # 查看所有文件/目录(包括隐藏文件,以.开头)ls -lh # 人性化显示文件大小(以KB、MB、GB显示)ls /home # 查看指定目录(/home)下的内容cat:查看文件全部内容,适合查看小文件。cat test.txt # 查看test.txt全部内容cat -n test.txt # 显示行号cat file1.txt file2.txt # 查看多个文件内容,合并输出more/less:查看大文件(分页显示),避免一次性输出过多内容。more test.txt # 分页查看,按空格键翻页,按q退出less test.txt # 分页查看,支持上下箭头滚动,按q退出(更灵活)head/tail:查看文件的前几行或后几行,常用於日志查看。head -5 test.txt # 查看前5行tail -5 test.txt # 查看后5行tail -f test.log # 实时监控日志文件(新增内容会实时显示,按ctrl+c退出)
(三)文件/目录修改:echo、vim、chmod、chown
这类命令用于修改文件内容、权限、所有者等属性,是文件操作的核心。
echo:向文件中写入内容(覆盖或追加)。echo "hello linux" > test.txt # 覆盖写入(原有内容会被清空)echo "file operation" >> test.txt # 追加写入(在原有内容末尾添加)vim:文本编辑器,用于编辑文件内容(Linux必备工具)。vim test.txt # 打开test.txt文件# 进入编辑模式:按i键# 编辑完成后,按esc键退出编辑模式,输入:wq保存并退出,:q!强制退出(不保存)chmod:修改文件/目录的权限(重点,面试高频)。 权限格式:r(读,4)、w(写,2)、x(执行,1),三类用户(所有者、所属组、其他用户)的权限相加,如755表示所有者rwx(4+2+1=7),所属组和其他用户r-x(4+0+1=5)。chmod 755 test.txt # 修改test.txt权限为755chmod u+x test.txt # 给所有者(u)增加执行权限(x)chmod g-w test.txt # 给所属组(g)移除写权限(w)chmod o=r test.txt # 给其他用户(o)设置只读权限(r)chmod -R 755 doc/ # 递归修改目录及子目录、文件的权限chown:修改文件/目录的所有者和所属组(需root权限,加sudo)。sudo chown user:user test.txt # 将test.txt的所有者和所属组改为usersudo chown -R user:user doc/ # 递归修改目录及内容的所有者和所属组
(四)文件/目录删除:rm
删除文件/目录,需谨慎使用(Linux没有回收站,删除后难以恢复),常用选项-f(强制删除,不提示)、-r(递归删除目录及内容)。
rm test.txt # 删除单个文件(会提示确认,按y确认) rm -f test.txt # 强制删除文件,不提示 rm -r doc/ # 递归删除目录及目录下的所有内容(会提示) rm -rf doc/ # 强制递归删除目录及内容(不提示,慎用!)警告:rm -rf /是高危命令,会删除根目录下的所有内容,导致系统崩溃,绝对禁止执行!
(五)文件/目录移动/复制:mv、cp
mv:移动文件/目录,也可用于重命名。mv test.txt doc/ # 将test.txt移动到doc目录下mv test.txt new_test.txt # 将test.txt重命名为new_test.txtmv doc/ /home/user/ # 将doc目录移动到/home/user目录下cp:复制文件/目录,常用选项-r(递归复制目录)、-v(显示复制过程)。cp test.txt doc/ # 将test.txt复制到doc目录下cp -r doc/ doc_copy/ # 递归复制doc目录,生成doc_copy目录(副本)cp -v file1.txt file2.txt # 复制文件,显示复制过程
(六)其他常用命令
find:查找文件/目录,按名称、大小、时间等条件查找(实用)。find /home -name "test.txt" # 在/home目录下查找名为test.txt的文件find . -size +10M # 在当前目录下查找大小超过10MB的文件find . -mtime -1 # 在当前目录下查找近1天内修改过的文件grep:在文件中查找指定字符串(文本搜索)。grep "hello" test.txt # 在test.txt中查找"hello"字符串grep -n "hello" test.txt # 显示匹配行的行号grep -r "hello" doc/ # 递归在doc目录下的所有文件中查找"hello"ln:创建硬链接和软链接(前面已提及,补充实操)。ln test.txt hard_link.txt # 硬链接,引用计数+1ln -s test.txt soft_link.txt # 软链接,引用计数不变
三、Linux文件操作系统调用(C语言,开发重点)
在Linux C/C++开发中,文件操作需通过系统调用实现,底层是内核提供的接口,常用的系统调用与前面的命令对应,核心分为“打开-读写-关闭”三步(文件操作的固定流程),结合之前学的进程知识,可实现更灵活的文件操作。
(一)核心系统调用介绍
所有文件操作的前提是“打开文件”,获取文件描述符(fd),后续操作通过fd操作文件,操作完成后关闭fd,释放资源(避免文件句柄泄漏)。
open():打开或创建文件,返回文件描述符(fd,非负整数,失败返回-1)。#include <fcntl.h>#include <unistd.h>// 函数声明int open(const char *pathname, int flags, mode_t mode);关键参数:示例:创建并打开一个文件,权限为0644:int fd = open("test.txt", O_RDWR | O_CREAT, 0644);if (fd == -1) {perror("open failed"); // 打印错误信息exit(1);}pathname:文件路径(绝对/相对);
flags:打开方式(如O_RDONLY只读、O_WRONLY只写、O_RDWR读写、O_CREAT创建文件);
mode:创建文件时的权限(如0644,对应rwx权限,与chmod一致)。
read():从文件中读取数据,返回实际读取的字节数(0表示读到文件末尾,-1表示失败)。#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);参数:fd(文件描述符)、buf(存储读取数据的缓冲区)、count(要读取的字节数)。write():向文件中写入数据,返回实际写入的字节数(-1表示失败)。#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);close():关闭文件,释放文件描述符(成功返回0,失败返回-1),必须调用,否则会导致文件句柄泄漏。#include <unistd.h>int close(int fd);
(二)完整示例:C语言实现文件读写
结合open、write、read、close四个系统调用,实现“创建文件→写入内容→读取内容→关闭文件”的完整流程:
#include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int fd; char buf[1024] = {0}; const char *content = "hello linux file operation!"; // 1. 打开/创建文件(读写模式,不存在则创建,权限0644) fd = open("test_syscall.txt", O_RDWR | O_CREAT, 0644); if (fd == -1) { perror("open failed"); exit(1); } printf("文件打开成功,文件描述符fd:%d\n", fd); // 2. 向文件写入内容 ssize_t write_len = write(fd, content, strlen(content)); if (write_len == -1) { perror("write failed"); close(fd); // 失败也要关闭文件,避免泄漏 exit(1); } printf("写入成功,写入字节数:%ld\n", write_len); // 3. 移动文件指针到开头(写入后指针在文件末尾,读取不到内容) lseek(fd, 0, SEEK_SET); // lseek用于移动文件指针 // 4. 从文件读取内容 ssize_t read_len = read(fd, buf, sizeof(buf)); if (read_len == -1) { perror("read failed"); close(fd); exit(1); } printf("读取成功,读取内容:%s\n", buf); // 5. 关闭文件 if (close(fd) == -1) { perror("close failed"); exit(1); } printf("文件关闭成功\n"); return 0; }编译运行:
gcc file_operation.c -o file_operation ./file_operation运行后会生成test_syscall.txt文件,包含写入的内容,同时终端输出读写结果。
(三)系统调用与命令的关联
我们日常使用的文件操作命令(如ls、cat、rm),底层本质都是调用这些系统调用实现的:
cat test.txt → 底层调用open()打开文件,read()读取内容,write()输出到终端,close()关闭文件;
rm test.txt → 底层调用unlink()系统调用(减少文件引用计数,计数为0则释放文件数据);
chmod 755 test.txt → 底层调用chmod()系统调用,修改文件权限。
四、文件操作的注意事项(避坑重点)
文件描述符泄漏:打开文件后必须调用close()关闭,否则会导致文件描述符耗尽,无法打开新文件(Linux默认每个进程最多打开1024个文件,可通过ulimit -n查看/修改)。
权限问题:操作文件时,需确保当前用户有对应权限(如写文件需要w权限,执行文件需要x权限),否则会报错“Permission denied”,可通过chmod、chown修改权限。
路径问题:使用相对路径时,需确认当前所在目录,避免因路径错误导致文件无法找到;推荐使用绝对路径,更稳妥。
删除文件需谨慎:Linux没有回收站,rm命令删除的文件难以恢复,尤其是rm -rf,建议删除前先使用ls查看文件/目录,确认无误后再删除。
引用计数与文件释放:硬链接会增加引用计数,只有所有硬链接都被删除,文件数据才会被释放;软链接不影响引用计数,原文件删除后软链接失效。
五、实操案例(巩固练习)
结合上述知识点,通过3个实操案例,巩固文件操作命令和系统调用的使用,可直接在Linux环境中练习:
案例1:文件操作基础练习。创建一个目录doc,在目录下创建test.txt文件,向文件中写入“Linux文件操作练习”,修改文件权限为755,查看文件内容和详细属性,最后删除该目录及文件。
案例2:查找与搜索。在/home目录下查找所有后缀为.txt的文件,在找到的文件中搜索“hello”字符串,显示匹配的文件路径和行号。
案例3:C语言文件读写。修改前面的系统调用示例,实现“读取一个已有文件的内容,复制到另一个新文件中”(模拟cp命令的底层逻辑)。
六、与前面知识点的关联
引用计数(refcount):文件的硬链接本质是增加引用计数,内核通过引用计数判断文件是否可释放,与之前学的进程PCB、内存页的引用计数逻辑一致。
进程与文件:每个进程都有自己的文件描述符表,记录打开的文件,进程退出时,内核会自动关闭所有未关闭的文件描述符(但仍建议手动close(),避免泄漏);fork创建的子进程会继承父进程的文件描述符(引用计数+1)。
IO密集型任务:文件读写属于IO操作,是典型的IO密集型任务,后续学习的异步IO、IO多路复用(epoll),都是为了优化文件/网络IO的效率。
七、总结
本节课重点讲解了Linux文件操作的核心知识点,核心要点总结如下:
Linux“一切皆文件”,文件分为5类,核心属性包括权限、引用计数、所有者等,路径分为绝对路径和相对路径。
常用文件操作命令按“创建-查看-修改-删除-移动/复制-权限管理”分类,重点掌握ls、cat、chmod、rm、mv、cp等命令的常用选项。
C语言文件操作通过系统调用实现,核心流程是“open→read/write→close”,需注意文件描述符泄漏问题。
文件操作与引用计数、进程、IO密集型任务密切相关,是后续学习异步IO、网络编程的基础。
文件操作是Linux日常使用和开发的基础,建议多在Linux环境中练习命令和系统调用,熟悉文件权限、路径、引用计数的逻辑,避免踩坑。下一篇笔记,我们将讲解Linux IO多路复用(epoll),进一步优化文件和网络IO的操作效率。
