Linux 文件 I/O(Input/Output)基础是 Linux 应用程序开发中的重要组成部分。在 Linux 系统中,文件 I/O 涉及到文件的读取和写入,以及文件描述符、系统调用等概念。以下是 Linux 文件 I/O 的基础知识:
1. 文件描述符
在 Linux 中,每个打开的文件都与一个文件描述符相关联。文件描述符是一个非负整数,表示进程中打开文件的引用。通常,文件描述符的值为 0、1 和 2,分别代表标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。
2. 打开文件
要在 Linux 中进行文件 I/O,首先需要打开文件。open
系统调用用于打开或创建文件,并返回文件描述符。
#include <fcntl.h>
#include <unistd.h>int main() {// 打开文件 example.txt,如果不存在则创建,以读写方式打开int fileDescriptor = open("example.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);// 其他文件 I/O 操作...// 关闭文件close(fileDescriptor);return 0;
}
3. 读取文件
read
系统调用用于从文件中读取数据。它接受文件描述符、缓冲区地址和读取的字节数作为参数。
#include <fcntl.h>
#include <unistd.h>
#include <iostream>int main() {int fileDescriptor = open("example.txt", O_RDONLY);char buffer[256];// 从文件中读取数据到缓冲区ssize_t bytesRead = read(fileDescriptor, buffer, sizeof(buffer));// 处理读取的数据std::cout << "Read " << bytesRead << " bytes: " << buffer << std::endl;close(fileDescriptor);return 0;
}
4. 写入文件
write
系统调用用于将数据写入文件。它接受文件描述符、缓冲区地址和写入的字节数作为参数。
#include <fcntl.h>
#include <unistd.h>int main() {int fileDescriptor = open("example.txt", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);const char* data = "Hello, Linux!";// 将数据写入文件ssize_t bytesWritten = write(fileDescriptor, data, strlen(data));// 处理写入的数据...close(fileDescriptor);return 0;
}
5. 移动文件指针
lseek
系统调用用于在文件中移动文件指针的位置。它接受文件描述符、偏移量和移动的位置(例如 SEEK_SET
、SEEK_CUR
、SEEK_END
)作为参数。
#include <fcntl.h>
#include <unistd.h>int main() {int fileDescriptor = open("example.txt", O_RDWR);off_t offset = lseek(fileDescriptor, 5, SEEK_SET); // 将文件指针移动到文件开头后的第 5 个字节// 处理文件指针位置...close(fileDescriptor);return 0;
}
6. 关闭文件
close
系统调用用于关闭文件。关闭文件后,与文件描述符相关联的资源将被释放。
#include <unistd.h>int main() {int fileDescriptor = open("example.txt", O_RDWR);// 其他文件 I/O 操作...// 关闭文件close(fileDescriptor);return 0;
}
7. 文件 I/O 错误处理
在进行文件 I/O 操作时,需要进行错误处理以处理可能发生的错误。通常,系统调用的返回值为 -1 表示发生了错误,此时可以使用全局变量 errno
获取错误码,并使用 perror
函数输出错误信息。
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <iostream>int main() {int fileDescriptor = open("nonexistent_file.txt", O_RDONLY);if (fileDescriptor == -1) {perror("Error opening file");std::cerr << "Error code: " << errno << ", Message: " << strerror(errno) << std::endl;return 1;}// 其他文件 I/O 操作...close(fileDescriptor);return 0;
}
8. 文件和目录操作
Linux 提供了一系列的文件和目录操作函数,可以用于获取和修改文件和目录的属性。以下是一些常见的文件和目录操作:
获取文件信息
使用 stat
函数可以获取文件的详细信息,包括文件类型、权限、大小等。
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>int main() {struct stat fileInfo;if (stat("example.txt", &fileInfo) == 0) {std::cout << "File size: " << fileInfo.st_size << " bytes" << std::endl;std::cout << "File permissions: " << (fileInfo.st_mode & 0777) << std::endl;// 其他文件信息...} else {perror("Error getting file information");}return 0;
}
创建和删除文件
使用 creat
函数可以创建新的文件,而 unlink
函数用于删除文件。
#include <fcntl.h>
#include <unistd.h>int main() {int fileDescriptor = creat("newfile.txt", S_IRUSR | S_IWUSR);if (fileDescriptor != -1) {// 文件创建成功// 其他文件 I/O 操作...close(fileDescriptor);} else {perror("Error creating file");}// 删除文件if (unlink("newfile.txt") == 0) {// 文件删除成功} else {perror("Error deleting file");}return 0;
}
创建和删除目录
使用 mkdir
函数可以创建新的目录,而 rmdir
函数用于删除目录。
#include <sys/stat.h>
#include <unistd.h>int main() {// 创建目录if (mkdir("newdir", S_IRWXU | S_IRWXG | S_IRWXO) == 0) {// 目录创建成功} else {perror("Error creating directory");}// 删除目录if (rmdir("newdir") == 0) {// 目录删除成功} else {perror("Error deleting directory");}return 0;
}
重命名和移动文件
使用 rename
函数可以重命名文件,而 rename
函数也可以用于移动文件。
#include <unistd.h>int main() {// 重命名文件if (rename("oldfile.txt", "newfile.txt") == 0) {// 文件重命名成功} else {perror("Error renaming file");}// 移动文件if (rename("sourcefile.txt", "targetdir/destinationfile.txt") == 0) {// 文件移动成功} else {perror("Error moving file");}return 0;
}
以上是一些文件和目录操作的基础概念,涵盖了获取文件信息、创建和删除文件、创建和删除目录、以及重命名和移动文件等操作。这些操作在实际应用程序开发中经常用到,根据需求可以选择合适的函数进行调用。