文件IO(系统IO)

一、系统IO
1.write
       #include

       ssize_t write(int fd, const void *buf, size_t count);
参数:
    fd:文件描述符
    buf:从buf里面拿数据写出去
    count:你想要写入到fd里面去的字节数
返回值:
    成功:返回你实际写入的字节数
    失败:-1

文件IO(系统IO)_第1张图片
总结:
char buf[1024] = "abcdefg";
ret = write(fd,buf,10);
printf("ret=%d\n",ret);    
当你的buffer里面只有7个字节,如果你想写入10个字节,实际返回值也是10;所以说count这个
参数的值,一定要按照你实际有效字节数来写;(注意它和read函数不一样)

2.lseek
       #include
       #include

       off_t lseek(int fd, off_t offset, int whence);
参数:
    fd:文件描述符
    offset:偏移量
    whence:基准坐标
           SEEK_SET 文件头
                      The offset is set to offset bytes.
           SEEK_CUR 当前位置
                      The offset is set to its current location plus offset bytes.
           SEEK_END 文件尾
                      The offset is set to the size of the file plus offset bytes.
返回值:
    成功:返回实际的偏移量(光标离文件头的的位置量)
    失败:-1

文件IO(系统IO)_第2张图片
练习1:
自己创建一个文件3.txt,随便在里面输入小于1024个字节
,通过lseek函数来计算出文件里面的字节数    
printf("file size=%d\n",ret);

说明:
 通常使用lseek(fd,0,SEEK_END)这种写法来文件大小

3.open函数的拓展
       #include
       #include
       #include

       int open(const char *pathname, int flags);(常用)
       int open(const char *pathname, int flags, mode_t mode);
参数:
    pathname:文件路径名
    flags:标志量
    mode:权限(手动创建的时候给它一个权限)
返回值:
    成功:新的文件描述符
    失败:-1
说明:
    如果想要使用mode这个变量给你创建的文件一个权限,不要在共享目录里面去验证;
因为共享目录是属于windows环境,在windows环境下给权限会与linux有冲突
1)验证要在家目录里面验证
2) 你给的权限和你实际得到的权限是经过运算后的值(umask)
3) 权限的运算不是数值上面的加减,而是某一位权限上面的数值的加减

4.文件和目录的权限
1)什么是umask
它可以影响一个文件和目录的起始权限

2)如何查看umask的值
gec@ubuntu:~/bling$ umask
0002
0002 --->表示当前系统的umask值
0      ----->第一个0是无效值
002  ----->有效的umask值

3)文件起始权限 = 666 - umask
    -rw- rw- rw-   (666)
           -     ---  ---  -w-    (002)
--------------------------------
    -rw- rw- r--     (664)    

4)目录的起始权限 = 777 - umask
    -rwx rwx rwx   (777)
           -     ---  ---   -w-    (002)
--------------------------------
    -rwx rwx r-x     (775)    

5)修改umask的起始权限
gec@ubuntu:~/bling$ umask 0000  (临时修改umask值为000)
gec@ubuntu:~/bling$ umask
0000
gec@ubuntu:~/bling$ ls -l
total 32
drwxrwxr-x 2 gec gec 4096 Jul 21 00:27 01
drwxrwxrwx 2 gec gec 4096 Jul 21 01:29 04   //修改之后的目录的权限是777
-rw-rw-r-- 1 gec gec    0 Jul 21 01:20 1.c
-rw-rw-rw- 1 gec gec    0 Jul 21 01:29 4.c    //修改之后的文件的权限是666

二、读写问题对光标移动的思考(对同一个文件描述符操作)
先读,再读
先读,再写
先写,再写
先写,再读
上面4种情况,光标位置都会随着你读写而改变;除非你手动用lseek函数去干预它光标的位置。

=========================================
LCD屏幕的操作
=========================================
一、按照接口类型来分类LCD屏幕
1.RGB (并行信号) -----GEC6818
2.LVDS (差分信号)
3.MIPI(mipi信号)----手机

文件IO(系统IO)_第3张图片

二、LCD
1.lcd的文件名
/dev/fb0   (framebuffer --- 帧缓冲)

2.lcd屏幕的大小分辨率(单位是像素点)
800*480(像素点)
说明:
      分辨率的大小和屏幕的尺寸大小,没有任何关系。

3.一个像素点等于多少个字节
一个像素点=4个字节
整个LCD屏幕的大小 = 800*480*4(字节)

4.一个像素点的组成部分(一个像素点的4个字节分别表示什么)
ARGB
A:  透明度 (按照理论上来说,如果我们给透明度一个值,颜色会有深浅之分,GEC6818没有变化)
R:  红色
G:绿色
B:蓝色

红色:0x00 ff 00 00
绿色:0x00 00 ff 00
蓝色:  0x00 00 00 ff
白色:0x00 ff  ff   ff
黑色:0x00 00 00 00

三、如何运用以上的知识点实现头顶一片绿
1.打开LCD
int fd;
fd = open("/dev/fb0",O_RDWR);
2.定义一个LCD的buffer
int buf[800*480] = {0};  //这种定义的方式就是给整个像素点赋值
3.往这一个LCD的buffer填值
for(y=0;y<480;y++)
{
    for(x=0;x<800;x++)
    {
        //当y=0 x=0,第0行第0个像素点
        //当y=1 x=1,第1行第1个像素点
        //当y=1 x=3,第1行第3个像素点
        buf[y*800+x] = green;
    }
}
4.将这一个buffer刷到LCD上去
write(fd,buf,800*480*4);

练习2:
德国国旗、法国国旗、比利时国旗等条状国旗

四、交叉编译
[root@GEC6818 /IOT]#mkdir bling
[root@GEC6818 /IOT]#cd bling/
[root@GEC6818 /IOT/bling]#rx lcd_arm
CC
开始 xmodem 传输。  按 Ctrl+C 取消。
  100%       6 KB    6 KB/s 00:00:01       0 Errors

[root@GEC6818 /IOT/bling]#chmod 777 lcd_arm 
[root@GEC6818 /IOT/bling]#ls
lcd_arm
[root@GEC6818 /IOT/bling]#./lcd_arm
 

作业:

一、文件的拷贝

拷贝大文件(循环拷贝)

比如说你拷贝一个图片1.jpg把他拷贝成2.jpg

1、观察2.jpg图片是否能正常打开

2、两张图片的字节大小是否一模一样

//需要两个文件描述符

while(1)

{

        read();

        write();

        //读取终止条件

        break;

}

二、附加题

变成指令

答案:

int main(int argc,char *argv[])

{

        int fd_src;

        int fd_dst;

        

        fd_src = open(argv[1],O_RDWR);

        if(fd_src < 0)

        {

                perror("open 1.jpg fail!\n");

                return -1;

       }

        

        fd_dst = open(argv[2],O_RDWR|O_CREAT);

        if(fd_dst < 0)

        {

                perror("open 2.jpg.fail!\n");

                return -1;

        }

        int i = 0;

        while(1)

        {

                char buf[1024] = {0};

                int ret_rd,ret_wr;

        

                ret_rd = read(fd_src,buf,1024);

                ret_wr = write(fd_dst,buf,ret_rd);

                printf("ret_rd:%d  ret_wr:%d  count:%d\n",ret_rd,ret_wr,++i);

                

                if(ret_rd == 0)//if(ret_rd < 1024)

                        break;

        }

        close(fd_src);

        close(fd_dst);

        return 0;

}

int fd1 = open(argv[1],O_RDWR,0664);
	int fd2 = open(argv[2],O_RDWR|O_CREAT,0664);
	

	int ret = lseek(fd1,0,SEEK_END);//查看原文件的大小
	printf("ret = %d\n",ret);
	char buf[ret];//内存缓冲
	
	lseek(fd1,0,SEEK_SET);//把光标移动回到最开始
	
	read(fd1,buf,ret);//读取数据
	
	write(fd2,buf,ret);//写入数据
	
	close(fd1);
	close(fd2);

 

你可能感兴趣的