文件读写


文件描述符

  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. 笔记:Hibernate DML

    Hibernate 提供的HQL(Hibernate Query Language)语句也支持批量 update 和 delete 语法,语法格式如下: [UPDATE | DELETE] FROM ...

  2. 从分布式一致性到共识机制(一)Paxos算法

    从分布式系统的CAP理论出发,关注分布式一致性,以及区块链的共识问题及解决. 区块链首先是一个大规模分布式系统,共识问题本质就是分布式系统的一致性问题,但是又有很大的不同.工程开发中,认为系统中存在故 ...

  3. Ubuntu16.0.4的磁盘管理

    ubuntu下硬盘无损分区移动修改工具 原创 2014年04月13日 :: ubuntu上面其实有很好的分区调整工具,gparted,非常好使用 安装非常简单 sudo apt-get install ...

  4. python全栈学习--day2

    一.in的使用 说明:in有相当多的用处,比如判断,循环for 等. 实例一:in 操作符用于判断关键字是否存在于变量中 s = '男人john' print('男孩' in s) print('男孩 ...

  5. 论文阅读——Visual inertial odometry using coupled nonlinear optimization

    简介:论文提出一种新的视觉里程计算法,其直接利用带噪声的IMU数据和视觉特征位置来优化相机位姿.不同于对IMU和视觉数据运行分离的滤波器,这种算法将它们纳入联合的非线性优化框架中.视觉特征的透视重投影 ...

  6. breeze源码阅读心得

            在阅读Spark ML源码的过程中,发现很多机器学习中的优化问题,都是直接调用breeze库解决的,因此拿来breeze源码想一探究竟.整体来看,breeze是一个用scala实现的基 ...

  7. 学号:201621123032 《Java程序设计》第9周学习总结(

    1:本周学习总结 1.1:以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容 2:书面作业 2.1: List中指定元素的删除(题集题目) 2.1.1:实验总结.并回答:列举至少2种在List ...

  8. cord-in-a-box 2.0 安装指南

    [TOC] 这篇文章简要介绍了 Ciab2.0 的安装. 包括硬件, 软件环境的选择, Ciab2.0的实际部署架构, 安装过程等. 下面就先对 Ciab2.0 部署环境做简要介绍. 1. 概述 这一 ...

  9. OO第一次作业总结

    OO第一次学习总结 1.第一次作业:多项式加法 从未接触过java的我,在从输入输出开始学了几天后,按照C语言的思路,写出了一个与面向过程极其接近的程序. 在这个程序中,存在两个类:一个是Comput ...

  10. 04_Linux目录文件操作命令1(mv ls cd...)_我的Linux之路

    上一节已经给大家讲了Linux的目录结构,相信大家已经对Linux的整个目录结构有所了解 现实中,服务器(包含Linux,Unix,windows server)一般都摆放在机房里,因为一个机房摆放了 ...