io函数 day3 文件io与系统函数
文件IO
- 概念:程序和文件系统之间的数据交互
- 特点:无缓冲区、不可移植、可访问多种文件类型、属系统调用、使用文件描述符
- 文件描述符
- 本质:数组下标,默认1024个,范围[0 - 1023]
- 申请规则:从小到大分配未申请的
- 特殊描述符:stdin(0)、stdout(1)、stderr(2)
- 文件IO函数
- open:打开文件
- 参数:路径文件名、访问模式(必选一种,可添加其他选项)、权限(与O_CREAT有关)
- 返回值:成功新描述符,失败-1
- umask:文件权掩码
- 查看:umask命令
- 修改:shell指令或函数
- close:关闭文件,参数为文件描述符
- write:写入数据,返回写入字节数
- read:读取文件,返回读取字符数
- lseek:文件指针偏移
- 参数:文件描述符、偏移量、起始位置
- 返回值:起始到当前位置偏移量
- open:打开文件
获取文件信息
- stat:获取文件信息(不包括软链接)
- 参数:路径文件名、存储信息结构体
- 返回值:成功0,失败-1
- getpwuid:根据用户id获取用户信息
- getgrgid:根据组id获取组信息
- 获取文件类型和权限
- 文件类型:由st_mode高4位决定
- 权限:由st_mode第9位决定
目录相关函数
- opendir:打开目录,返回目录流指针
- closedir:关闭目录流指针
- readdir:读取目录信息,返回结构体
作业:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "headhs.h"
int main(int argc, const char *argv[])
{
// 打开 BMP 文件
int fd = open("xiaoxin.bmp", O_RDONLY);
if (fd < 0)
pt_er("打开文件失败");
// ------------------------- 文件头 (14字节) -------------------------
// 1. 读取文件类型 (偏移 0x00, 2字节)
unsigned short bfType;
lseek(fd, 0x00, SEEK_SET);
if (read(fd, &bfType, sizeof(bfType)) <= 0)
pt_er("读取文件类型失败");
if (bfType != 0x4D42) // "BM" 的十六进制小端表示是 0x424D,但需根据系统字节序调整
pt_er("非标准BMP文件(需为BM类型)");
printf("文件类型: 0x%04X (BM)\n", bfType);
// 2. 读取文件大小 (偏移 0x02, 4字节)
unsigned int bfSize;
lseek(fd, 0x02, SEEK_SET);
if (read(fd, &bfSize, sizeof(bfSize)) <= 0)
pt_er("读取文件大小失败");
printf("文件大小: %u 字节\n", bfSize);
// 3. 读取像素数据偏移量 (偏移 0x0A, 4字节)
unsigned int bfOffBits;
lseek(fd, 0x0A, SEEK_SET);
if (read(fd, &bfOffBits, sizeof(bfOffBits)) <= 0)
pt_er("读取像素数据偏移量失败");
printf("像素数据偏移量: %u 字节\n", bfOffBits);
// ---------------------- 位图信息头 (40字节) ----------------------
// 4. 读取信息头大小 (偏移 0x0E, 4字节)
unsigned int biSize;
lseek(fd, 0x0E, SEEK_SET);
if (read(fd, &biSize, sizeof(biSize)) <= 0)
pt_er("读取信息头大小失败");
printf("信息头大小: %u 字节\n", biSize);
// 5. 读取图像宽度 (偏移 0x12, 4字节)
int biWidth;
lseek(fd, 0x12, SEEK_SET);
if (read(fd, &biWidth, sizeof(biWidth)) <= 0)
pt_er("读取图像宽度失败");
printf("宽度: %d 像素\n", biWidth);
// 6. 读取图像高度 (偏移 0x16, 4字节)
int biHeight;
lseek(fd, 0x16, SEEK_SET);
if (read(fd, &biHeight, sizeof(biHeight)) <= 0)
pt_er("读取图像高度失败");
printf("高度: %d 像素\n",biHeight);
// 7. 读取位平面数 (偏移 0x1A, 2字节)
unsigned short biPlanes;
lseek(fd, 0x1A, SEEK_SET);
if (read(fd, &biPlanes, sizeof(biPlanes)) <= 0)
pt_er("读取位平面数失败");
printf("位平面数: %hu\n", biPlanes);
// 8. 读取每像素位数 (偏移 0x1C, 2字节)
unsigned short biBitCount;
lseek(fd, 0x1C, SEEK_SET);
if (read(fd, &biBitCount, sizeof(biBitCount)) <= 0)
pt_er("读取每像素位数失败");
printf("每像素位数: %hu\n", biBitCount);
// 9. 读取压缩方式 (偏移 0x1E, 4字节)
unsigned int biCompression;
lseek(fd, 0x1E, SEEK_SET);
if (read(fd, &biCompression, sizeof(biCompression)) <= 0)
pt_er("读取压缩方式失败");
printf("压缩方式: %u (0=无压缩)\n", biCompression);
// 10. 读取图像数据大小 (偏移 0x22, 4字节)
unsigned int biSizeImage;
lseek(fd, 0x22, SEEK_SET);
if (read(fd, &biSizeImage, sizeof(biSizeImage)) <= 0)
pt_er("读取图像数据大小失败");
printf("图像数据大小: %u 字节\n", biSizeImage);
// 11. 读取水平分辨率 (偏移 0x26, 4字节)
int biXPelsPerMeter;
lseek(fd, 0x26, SEEK_SET);
if (read(fd, &biXPelsPerMeter, sizeof(biXPelsPerMeter)) <= 0)
pt_er("读取水平分辨率失败");
printf("水平分辨率: %d 像素/米\n", biXPelsPerMeter);
// 12. 读取垂直分辨率 (偏移 0x2A, 4字节)
int biYPelsPerMeter;
lseek(fd, 0x2A, SEEK_SET);
if (read(fd, &biYPelsPerMeter, sizeof(biYPelsPerMeter)) <= 0)
pt_er("读取垂直分辨率失败");
printf("垂直分辨率: %d 像素/米\n", biYPelsPerMeter);
// 13. 读取使用的颜色数 (偏移 0x2E, 4字节)
unsigned int biClrUsed;
lseek(fd, 0x2E, SEEK_SET);
if (read(fd, &biClrUsed, sizeof(biClrUsed)) <= 0)
pt_er("读取使用的颜色数失败");
printf("使用的颜色数: %u\n", biClrUsed);
// 14. 读取重要颜色数 (偏移 0x32, 4字节)
unsigned int biClrImportant;
lseek(fd, 0x32, SEEK_SET);
if (read(fd, &biClrImportant, sizeof(biClrImportant)) <= 0)
pt_er("读取重要颜色数失败");
printf("重要颜色数: %u\n", biClrImportant);
// 关闭文件:
close(fd);
return 0;
}