Linux文件操作---随手记

文件定义

狭义

磁盘文件,进而可以是有组织有次序地存储在任何介质(包括内存)中的一组信息

广义

凡是可以产生或者消耗信息的都是文件。(也包括socket)

文件操作方式

系统调用库函数
openfopen
readfread
writefwrite
closefclose
lseek, ioctl…fseek, fgetc, fputc…

系统调用:linux system call 类似windows 的api,为linux特有的系统操作,其中有关文件的操作有:pen, read, write, close, lseek, ioctl, 等
库函数:库函数是编程语言提供的函数集合,比如C的标准输入输出库:stdio.h 提供了以下函数fopen, fread, fwrite, fclose, fflush fseek, etc.
,这些函数不局限于linux操作系统,其他支持该C标准库的操作系统同样可以使用。
在linux 中,库函数对文件的操作实际是对系统调用的相关操作的封装。

创建

系统调用参数
Int creat(const char *filename,mode_t mode)参数mode指定新建文件的读写权限,与umask共同决定文件的最终权限。Umask代表文件创建时去掉默写读写权限,可通过系统调用 int umask(int newmask)修改

打开

系统调用

int open(const char *pathname, int flags); 
int open(const char *pathname, int flags, mode_t mode); 

例子

open(“test”, O_CREAT, 10705)
open(“test”, O_CREAT,  S_IRWXU | S_IROTH | S_IXOTH | S_ISUID)

C库函数

FILE *fopen(const char *path, const char *mode);
ModeComment
r,rb只读打开
W,wb只写打开,文件不存在则创建
a,ab追加方式打开(只写),文件不存在则创建
r+,r+b,rb+读写方式打开
w+,w+b,wh+读写方式打开,文件不存在则创建
a+,a+b,ab+追加读写打开,文件不存在则创建

读写

系统调用

int read(int fd, const void *buf, size_t length);

从文件描述符fd指定的文件中读取length个字节到buf缓冲区

int write(int fd, const void *buf, size_t length);

length个字节从buf缓冲区写入到文件描述符fd指向的文件中

C库函数

int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
char *fgets(char *s, int n, FILE *stream);
int fputs(const char *s, FILE *stream);
int fprintf(FILE *stream, const char *format, ...);
int fscanf (FILE *stream, const char *format, ...);
Size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
Size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream);

定位

系统调用

int lseek(int fd, offset_t offset, int whence); 

作用,移动当前读写位置,offset含义取决于whence。
返回值:新的偏移量(成功),-1(失败)

whenceoffset含义
SEEK_SET文件偏移量将被设置为 offset
SEEK_CUR文件偏移量将被设置为 cfo (当前文件偏移量)加上 offset
SEEK_END文件偏移量将被设置为文件长度加上 offset

技巧:currpos = lseek(fd, 0, SEEK_CUR) 返回当前的文件偏移量

C库函数

int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, const fpos_t *pos);
int fseek(FILE *stream, long offset, int whence); 

关闭

系统调用C库函数
int close(int fd);int fclose (FILE *stream);

示例——文本复制

系统调用

#include <unistd.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stdlib.h>  
 
int main()  
{  
    char c = '\0';  
    int in = -1, out = -1;  
    in = open("Data.txt", O_RDONLY);  
    out = open("copy_system.out.txt", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);  
    while(read(in, &c, 1) == 1)
         {
            write(out, &c, 1);
         }
    close(in);  
    close(out);  
    return 0;  
}  

C库函数

#include <stdio.h>  
#include <stdlib.h>  
  
int main()  
{  
    int c = 0;  
    FILE *pfin = NULL;  
    FILE *pfout = NULL;  
     pfin = fopen("Data.txt""r");  
    pfout = fopen("copy_stdio.out.txt""w");     
    while(fread(&c, sizeof(char), 1, pfin))
{
        fwrite(&c, sizeof(char), 1, pfout);
}
    fclose(pfin);  
    fclose(pfout);  
    return 0;  
} 

区别

系统调用(open)C库函数(fopen)
int open(const char *path, int access,int mode)FILE *fopen(char *filename, char *mode)
非缓冲操作缓冲操作
返回 文件描述符返回 文件指针
可用来操作设备文件,套接字,普通文件等一般只操作普通文件,不能操作设备文件
在linux中由内核实现文件操作在linux中间接调用系统调用open
只针对linux多操作系统移植

文件层次

底层上,linux文件系统包括Ext2,等。
向上,则为用户程序提供一个统一的,抽象的,虚拟的文件系统界面。也就是所谓的虚拟文件系统-VFS(virtual filesystem ),虚拟文件系统为用户程序提供了一组标准的,抽象的文件操作——read ,write,lseek 等。也就是我们所谓的 系统调用。(文件操作包括 系统调用和库函数)

图1
这里写图片描述

系统调用open是如何调用驱动的open的

注册字符设备

file_operations misc_fops = { .open= misc_open};
register_chrdev(MISC_MAJOR,”misc”,&misc_fops)

图2
这里写图片描述

系统调用open

图3
这里写图片描述

进程中文件操作的结构

图4
这里写图片描述

Android中的文件系统

Init.rc中的文件分区与文件属性

CommandComment
chmod 改变文件访问权限
chown 改变文件所属和组
mkdir [mode] [owner] [group]在创建一个目录,可选选项:mod,owner,group.如果没有指定,目录以755权限,owner为root,group为root创建.
mount [ ]*尝试mount 到目录. 可以用mtd@name格式以命名指定一个mtd块设备。包含”ro”,”rw”,”remount”,”noatime”
write [ ]*打开的文件并写入一个或多个字符串。

挂载ROM分区到 /system;/data;/cache 分区:

mount ext4 /dev/block/mmcblk0p9 /system ro wait noatime
mount ext4 /dev/block/mmcblk0p12 /data wait nosuid nodev noatime discard
mount ext4 /dev/block/mmcblk0p8 /cache nosuid nodev noatime journal_async_commit

noatime:Linux缺省每次读文件,都要更新这个文件的last access time属性,增加这个noatime选项,则在读文件时不去更改文件的access time属性了,提高文件系统性能

文件属性简介

Linux文件可以分为如普通文件、目录、符号链接文件、字符和块设备文件、套接口文件等。
Umask-代表“剥夺”的权限
Mode 的助记表示法
-R参数循环设置目录下的所有文件及目录
setuid和setgid 位-setuid 和 setgid “ ” 是让程序执行的时候 临时的 的拥有了程序
文件所有者的 uid 和 gid,等程序执行完后再恢复到发起者的权限。
对于目录,如果在某个目录上设置了 setgid 位以后,在这个目录中创建的文件具有该目录的属组权限而不是创建该文件的用户的默认属组

Sticky粘贴位(较少用到)-一个目录即使它的所有权限都开放rwxrwxrwx,如果是设置了粘帖位,除非目录的属主和root用户有权限删除它,除此之外其它用户不能删除这个目录,用途一般是把一个文件夹的的权限都打开,然后来共享文件,象/tmp目录一样。

命令ls -lih
显示结果699679673 -rw-r–r– 1 xxxxx xxxxx 681 2013-05-24 09:16 Android.mk
显示结果688685627 -rw-r–r– 1 xxxxx xxxxx 0 2013-05-24 11:02 Version.inc
涵义(一一对应)Inode;文件种类和权限;硬链接个数;User;Group;大小;最后访问/修改时间;文件/目录名
技巧上面的Version.inc显示有一个硬链接,通过find -inum 688685627可以查找对应硬链接文件,结果另一个文件位于./vendor/Version.inc

Android文件系统的初始权限

tmpfs文件系统类型是基于虚拟内存的文件系统
rootfs,也是一种基于RAM的文件系统,可以看到Android的/是直接建立在RAM上的

android/system/core/include/private/android_filesystem_config.h
定义了各个用户及用户组,并定义了部分目录的用户,用户组,读写权限

Android 系统编译时会使用两个 Android 命令 mkbootfs 和 mkyaffs2image 来生成这些 img文件,这两个命令都会调用文件 android_filesystem_config.h 中预制的权限,来写入这些目录和文件资源初始的访问权限


#define AID_ROOT             0
#define AID_SYSTEM        1000
#define AID_RADIO         1001
…………………………

static struct fs_path_config android_dirs[] = {
    { 00770, AID_SYSTEM, AID_CACHE,  "cache" },
    { 00771, AID_SYSTEM, AID_SYSTEM, "data/app" },
    { 00771, AID_SYSTEM, AID_SYSTEM, "data/app-private" },
    { 00771, AID_SYSTEM, AID_SYSTEM, "data/dalvik-cache" },
    { 00771, AID_SYSTEM, AID_SYSTEM, "data/data" },
    //可以在此处添加新增目录的权限

分别对应:Mode uid gid *prefix


static const struct android_id_info android_ids[] = {
    { "root",      AID_ROOT, },
    { "system",    AID_SYSTEM, },
    { "radio",     AID_RADIO, },
 …………………………

分别对应Name和aid


static struct fs_path_config android_files[] = {
    { 00440, AID_ROOT,      AID_SHELL,     "system/etc/init.goldfish.rc" },
    { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.goldfish.sh" },
    { 00440, AID_ROOT,      AID_SHELL,     "system/etc/init.trout.rc" },
    { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.ril" },
    //可以在此处添加新增文件的权限

分别对应:Mode uid gid *prefix

新增设备权限

android/system/core/rootdir/ueventd.rc

/dev/null                 0666   root       root
/dev/zero                 0666   root       root
/dev/full                 0666   root       root
/dev/ptmx                 0666   root       root
/dev/tty                  0666   root       root
/dev/random               0666   root       root
/dev/urandom              0666   root       root
/dev/ashmem               0666   root       root
/dev/binder               0666   root       root
新增设备时在此文件中添加权限

对于新添加的设备,需要在该文件中添加对应的设备权限,否则可能出现无法使用的情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值