文件读写


文件描述符

  Linux下,通常通过open打开一个文件,它然后返回给我们一个整数,通过这个整数便可以操作文件,这个整数我们称文件描述符(fd)。对应被打开的文件,它也是一种系统资源,那么fd打的能打开多少个文件呢?可以通过这两个命令查看

ulimit –n        //查看系统打开文件的数据

ulimit –n  数值    //将打开文件修改为数值大小。

系统到底能打开多少文件由什么决定?

是一个叫file-max的配置文件决定的。可以通过 cat  / proc/sys/fs/file_amx  查看文件打开数目的最大值 (1G大小相当于可打开10万个文件)

【open函数】

文件打开函数open有两种

头文件 #include <fcntl.h>
int open(const char* pathname , //打开文件名
int flag) O_RDONLY //只读
O_WRONLY //只写
O_RDWR //读写
O_CREAT //打开的同时创建(如果文件存在就不创建)
O_TRUNC //打开时清除文件内容
         O_EXCL //若O_CRETE和O_EXCL被设置且文件存在,open调用失败
         O_NDELAY //延迟读写标记
int open(const char* pathname, //文件路径
int flags, // 与前面相同
mode_t mode); //文件存取权限标志 如 666; 注意:参数flag必须在O_RDONLY,O_WRONLY,O_RDWR中有且只能选取一个,然后用"|"符合于其他标准组合(相当于或起来)。函数调用成功时返回打开的文件描述符,失败返回-1.
文件描述符分配规则:从小到大找到第一个没有被分配使用的文件描述符。
查看该进程文件描述符: /proc/pid/fd (pid 当前进程标识符)

【系统IO:read  write】

//ssize_t int  =  size_t unsigned int
size_t write(int fd ,
const void* buf, //想写入的数据位置
size_t len) //要写入数据大小 返回实际写入的字节数,在合适的时机将数据从内核区写入磁盘
ssize_t read(int fd,    //open打开的文件描述符
void* buf, //用户准备的缓存区
size_t count) //缓存区大小 返回读取的字节数,(如果返回值为0,表示读取结束),顺序读写文件

read/write函数调用不仅可以用于普通文件,还适用于管道、流设备和设备文件。多个程序同时读写一份文件,会产生竞争问题,若希望按预定次序进行读写,则应使用文件锁。

2. 定位文件的当前读写位置:off_t lseek(int fd, off_t offset, int whence)

off_t lseek(int fd,
off_t offset,    //偏移量
int whence)   //基准位置 有如下3个基准:
  SEEK_SET
  SEEK_CUR
   SEEK_END
函数返回值:新定位的读写位置,失败返回-1.

作用:可以通过它来求得文件大小

先写入一个文件:

 #include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include <sys/stat.h>
#include <fcntl.h> void main()
{
int file_size = *;
int fd=open("test.txt", O_RDWR);
if(fd < )
{
perror("open test.txt");
exit(-);
}
lseek(fd, file_size-, SEEK_END);
write(fd,"", );
close(fd); }

lseek创建一文件

结果:得到了1M字节的.txt文件

tp@tp:~/Linux/day3$ vim test.txt
tp@tp:~/Linux/day3$ ls -lh
total 24K
-rw-rw-r-- tp tp Apr : .cpp
-rw-rw-r-- tp tp Apr : abc.txt
-rwxrwxr-x tp tp .7K Apr : a.out
-rw-rw-r-- tp tp Apr : lseek.c
-rw-rw-r-- tp tp Apr : test.txt
tp@tp:~/Linux/day3$ gcc lseek.c
tp@tp:~/Linux/day3$ ./a.out
tp@tp:~/Linux/day3$ ls -lh
total 28K
-rw-rw-r-- tp tp Apr : .cpp
-rw-rw-r-- tp tp Apr : abc.txt
-rwxrwxr-x tp tp .7K Apr : a.out
-rw-rw-r-- tp tp Apr : lseek.c
-rw-rw-r-- tp tp 1.0M Apr : test.txt

利用lseek求文件大小

 #include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include <sys/stat.h>
#include <fcntl.h> void main()
{
int fd=open("test.txt", O_RDWR);
if(fd < )
{
perror("open test.txt");
exit(-);
}
printf("file size:%ld\n",lseek(fd, , SEEK_END));
close(fd); }

利用lseek获取文件大小

结果:

tp@tp:~/Linux/day3$ gcc lseek.c
tp@tp:~/Linux/day3$ ./a.out
file size:
tp@tp:~/Linux/day3$ du -h test.txt
.0K test.txt

注意:①ls –l 查看文件字符数  ②du –h 查看实际占用的物理磁盘块数

来看看test.txt里面的内容:

用od 命令来查看文件中不能直接显示在终端的字符:

tp@tp:~/Linux/day3$ od -s test.txt 

*

注意到 有一个“*”存在,这其实就是空洞文件,它指没有被实际写入文件的所有字节。这些字节由重复的 0 表示。(据百度百科还是由于offset > 实际文件大小所致)

同时,因为ls展现的是文件的逻辑大小,即在文件系统表现出来的大小,而du展现的是文件物理大小,也就是文件在磁盘上实际所占的block数;所以说,空洞文件在文件系统表现的还是和普通文件一样的,但是实际上文件系统并没有给他分配所表现出来的那么多空间,只是存放了有用的信息。

【dup命令】

原型   #include <unistd.h>
     int dup(int oldfd);
    int dup2(int oldfd, int newfd);

说明:

  dup用来复制oldfd所指的文件描述符。但返回的是最小且当前尚未被使用的文件描述符,若有错误则返回-1,错误代码存入errno中。返回的新文件描述符就会和oldfd指向同一个文件,共享所有的锁定,读写指针,和各项权限或标志位。
    dup2可以用参数newfd指定新文件描述符的数值。若newfd已经被程序使用,系统就会将其关闭以释放该文件描述符;若newfd与oldfd相等,dup2将返回newfd,而不关闭它。dup2调用成功返回新的文件描述符,出错则返回-1。

文件描述符在PCB里面一张文件描述符表存着,且0,1,2 代表标准输入,标准输出,标准出错。

应用:结合前面的文件操作函数,可以实现“输出重定向”

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include <sys/stat.h>
#include <fcntl.h> int main(void)
{
int fd;
if((fd = open("test1.txt", O_RDWR|O_CREAT))== -)
{
perror("open error");
exit();
}
close(); //关闭标准输出
dup(fd); //复制fd文件描述符返回到当前最小可用文件描述1(标准输出)
//此时 1和fd指向同一个文件表(如上图)
// dup2(fd, 1); //和dup类似,不过它可以直接为oldfd指定成为newfd文件描述符数值
close(fd); //关闭oldfd
printf("gggggg\n");
return ;
}
结果:
  

磁盘


磁盘分类:

   ①IDE接口类型  如hda,hdb,hdc. 等。 hda一般指第一块硬盘,IDE类型安装更方便

   ②SCSI (SARA)接口类型    linux下通常是此种类型的接口硬盘,如sda。 linux下,u盘、硬盘通常被识别为此种类型。

区别:

           U盘和SARA硬盘的在Linux上面的文件名一般是 /dev/sd[a-p]。与IDE接口不同的是,SCSI/USB接口的磁盘没有固定的顺序,一般根据Linux内核检测到磁盘的顺序检测。

相关命令:

   lsblk [选项] [设备]    // 查看分区使用情况

   df [选项] [查看文件名]  //查看磁盘使用情况

自己挂载一块硬盘

步骤:


1. 进入虚拟机设置 按引导创建一块新硬盘,如

    

  然后重启虚拟机。

2. 分区  使用fdisk /dev/sdb

   此时 lsblk ,查看到多了一个1G的硬盘(disk)

    

   然后 fdisk  /dev/sdb  

tp@Bit:~$ sudo fdisk /dev/sdb
[sudo] password for tp: Welcome to fdisk (util-linux 2.30.).
Changes will remain in memory only, until you dec
Be careful before using the write command. Device does not contain a recognized partition ta
Created a new DOS disklabel with disk identifier Command (m for help): m

  输入m 可以查看帮助,n:代表新创建分区,p:列出分区表,w:把分区表写入硬盘并退出

Command (m for help): n
Partition type
p primary ( primary, extended, free)
e extended (container for logical partitions)
Select (default p): p
Partition number (-, default ):
First sector (-, default ):
Last sector, +sectors or +size{K,M,G,T,P} (-, default ): Created a new partition of type 'Linux' and of size MiB. Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

3. 格式化磁盘   mkfs  -t  ext4 /dev/sdb1

  此时,lsblk 一下 sdb下面就已创建了分区

tp@Bit:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda : 20G disk
└─sda1 : 20G part /
sdb : 1G disk
└─sdb1 : 1023M part
sr0 : .4G rom
tp@Bit:~$ sudo mkfs -t ext4 /dev/sdb1
mke2fs 1.43. (-Aug-)
/dev/sdb1 contains a ext4 file system
created on Fri Apr ::
Proceed anyway? (y,N) y
Creating filesystem with 4k blocks and inodes
Filesystem UUID: fe547447-dd2e-423e-bd17-af8078c09fb5
Superblock backups stored on blocks:
, , , Allocating group tables: done
Writing inode tables: done
Creating journal ( blocks): done
Writing superblocks and filesystem accounting information: done

4. 挂载  mount  [挂载目录] [被挂载目录]   (重启后挂载的硬盘会消失)

  

  此时,myDisk目录下出现lost+found 目录。 挂载成功。

5. 自动挂载   /etc/fstab      

  以上面的挂载方式,就可以为U盘,新插硬盘进行挂载了,但是当重启虚拟机以后,我们挂载的目录可能就找不到了,因为它没有添加到配置文件里面,所以不能像 / 目录那样自动挂载。如要自动挂载的话,就还得为相应配置文件添加内容。

先打开配置文件  /etc/fstab ,然后添加 :

/dev/sdb1    /myDisk   ext4     defaults      

各选项分别是:1.挂载目录
       2.被挂载点
       3.文件系统类型
       4.挂载选项
       5.设置是否使用dump备份,置0为不备份,置1,2为备份,但2的备份重要性比1小
       6.设置是否开机的时候使用fsck检验所挂载的磁盘,置0为不检验,置1,2为检验,但置2盘比置1的盘晚检验。

  

  df -h 一下

  

  ok! 挂载完成。

6. 卸载    umount  [挂载目录] [被挂载目录]

  没配置,直接umount就可以了;配置了配置文件,将配置文件改回,再umount。

Linux 文件读写操作与磁盘挂载的更多相关文章

  1. c语言文件读写操作总结

    C语言文件读写操作总结 C语言文件操作 一.标准文件的读写 1.文件的打开 fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程 ...

  2. [转]Android - 文件读写操作 总结

     转自:http://blog.csdn.net/ztp800201/article/details/7322110 Android - 文件读写操作 总结 分类: Android2012-03-05 ...

  3. PHP文件读写操作之文件写入代码

    在PHP网站开发中,存储数据通常有两种方式,一种以文本文件方式存储,比如txt文件,一种是以数据库方式存储,比如Mysql,相对于数据库存储,文件存储并没有什么优势,但是文件读写操作在基本的PHP开发 ...

  4. Java 字节流实现文件读写操作(InputStream-OutputStream)

    Java 字节流实现文件读写操作(InputStream-OutputStream) 备注:字节流比字符流底层,但是效率底下. 字符流地址:http://pengyan5945.iteye.com/b ...

  5. Java 字符流实现文件读写操作(FileReader-FileWriter)

    Java 字符流实现文件读写操作(FileReader-FileWriter) 备注:字符流效率高,但是没有字节流底层 字节流地址:http://pengyan5945.iteye.com/blog/ ...

  6. python(三)一个文件读写操作的小程序

    我们要实现一个文件读写操作的小程序 首先我们有一个文件 我们要以"============"为界限,每一个角色分割成一个独立的txt文件,按照分割线走的话是分成 xiaoNa_1. ...

  7. 实现动态的XML文件读写操作

    实现动态的XML文件读写操作(依然带干货) 前言 最近由于项目需求,需要读写操作XML文件,并且存储的XML文件格式会随着导入的数据不同而随时改变(当然导入的数据还是有一定约束的),这样我们要预先定义 ...

  8. ios 简单的plist文件读写操作(Document和NSUserDefaults)

    最近遇到ios上文件读写操作的有关知识,记录下来,以便以后查阅,同时分享与大家. 一,简单介绍一下常用的plist文件. 全名是:Property List,属性列表文件,它是一种用来存储串行化后的对 ...

  9. java文件读写操作类

    借鉴了项目以前的文件写入功能,实现了对文件读写操作的封装 仅仅需要在读写方法传入路径即可(可以是绝对或相对路径) 以后使用时,可以在此基础上改进,比如: 写操作: 1,对java GUI中文本框中的内 ...

随机推荐

  1. 使用pm2躺着实现负载均衡

    事实上,pm2 是一个带有负载均衡功能的Node应用的进程管理器,Node实现进程管理的库有很多,forever也是其中一个很强大但是也相对较老的进程管理器. 为什么要使用pm2 对于这个问题,先说说 ...

  2. 配置SecureCRT以SSH公钥方式登录服务器

    为了更方便管理服务器,CRT一个功能非常方便.那就是可以使用私钥认证通过后直接连接,而且对于密码保护比较安全一点. 首先配置ssh Port 32812Protocol 2UseDNS noPubke ...

  3. 真是没想到,ikvm.net居然停止开发了。

    看样子作者对.net已经失去了信心 http://weblog.ikvm.net/CommentView.aspx?guid=33ea525f-a291-418a-bd6a-abdf22d0662b# ...

  4. 云计算--网络原理与应用--20171120--VLAN与三层交换机配置

    什么是VLAN及其配置 Trunk的原理与配置 三层交换机的基本配置 实验:配置一个三层交换机 一 VLAN 的概念及优势 VLAN(virtual local area network)就是虚拟局域 ...

  5. JavaScript(第三十二天)【Ajax】

    2005年Jesse James Garrett发表了一篇文章,标题为:"Ajax:A new Approach to Web Applications".他在这篇文章里介绍了一种 ...

  6. Beta第二天

    听说

  7. Alpha第四天

    Alpha第四天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  8. 1013团队Beta冲刺day1

    项目进展 李明皇 今天解决的进度 点击首页list相应条目将信息传到详情页 明天安排 优化信息详情页布局 林翔 今天解决的进度 前后端连接成功 明天安排 开始微信前端+数据库写入 孙敏铭 今天解决的进 ...

  9. 局域网下访问其他计算机搭建的django网页

    1.修改工程目录下的setting.py 文件 ALLOWED_HOSTS = ['*'] #*表示允许访问的ip 如果是添加* 则允许所有同局域网环境的主机访问 2.在完成的django工程下运行以 ...

  10. Node入门教程(4)第三章:第一个 Nodejs 程序

    第一个 Nodejs 程序 本教程仅适合您已经有一定的JS编程的基础或者是后端语言开发的基础.如果您是零基础,建议您先学一下老马的前端免费视频教程 第一步:创建项目文件夹 首先创建 demos 文件夹 ...