起因

近期在调试一个Android播放内核是遇到上层传递的是fd(file descriptor),但是在文件播放结束之后调用lseek却提示返回-1,errno=29(#define ESPIPE 29 /* Illegal seek */)。

好吧。那就确定下原因。

在网上搜到有说lseek存在问题,“对于已经到达EOF的stream,使用lseek是不能让stream再次可读的”。具体参考Android NDK之fseek, lseek。随即写了个命令行程序,在android shell下验证了下,经过验证是可以的。那就继续找吧。

最终发现一个有趣的现象,Android的MediaServer传递的fd只能在调用时使用,之后就被复用了,指针都改变了。具体发现的方法就是本文描述的内容。

文件操作

文件操作比较通用的就是C库的FILE(带缓冲的文件流),也就是常用的fopen, fclose, fprintf, fscanf, fseek, fread, fwrite等函数。这里面比较核心的概念是FILE结构,这是C库提供的跨平台的文件操作函数,多数情况下是封装了系统内核提供的文件读写函数,比如在windows下是CreateFile, CloseFile, OpenFile, WriteFile, ReadFile等函数,在linux下是open, close, lseek, read, write等内核API。

在linux下内核API主要提供了基于文件描述(FD,file descriptor)的文件操作机制,注意FD默认是非负的,通常0-stdin、1-stdout、2-stderr。

先看看如何实现FILE到fd的转换,函数fileno可以实现这种转换,原型如下:

int fileno(FILE *stream);

那么fd如何转换为FILE呢? 函数fdopen可以基于FD打开文件,原型如下:

FILE *fdopen(int fd, const char *mode);

那么如何通过fd拿到文件原始路径呢? 函数readlink提供了这种机制,可以参考下面代码

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

FILE * stream = fopen(__FILE__, "rb");

if (NULL == stream)

{

printf("open %s failed\n", __FILE__);

return -1;

}

int fd = fileno(stream);

char buf[4096] = {0};

// read to file end

while (read(fd, buf, sizeof(buf)) > 0);

// test whether lseek is ok in EOF

off_t offset = lseek(fd, 0, SEEK_CUR);

printf("lseek ret %d err_no %d\n", offset, errno);

// read file path from fd

char path[PATH_MAX] = {0};

snprintf(path, sizeof(path), "/proc/%d/fd/%d", getpid(), fd);

memset(buf, 0, sizeof(buf));

int buf_size = readlink(path, buf, sizeof(buf));

if (buf_size < 0)

{

printf("readlink() ret %d error %d\n", buf_size, errno);

}

else

printf("readlink() returned '%s' for '%s'\n", buf, path);

getchar();

if (NULL != stream)

fclose(stream);

return 0;

}

原理很简单,linux下的fd就是一个链接,可以通过/proc/pid/fd读取到相关信息。

比如上面那个程序的输出如下:

/proc/11203/fd$ ll

总用量 0

dr-x------ 2 root root 0 4月 1 15:48 ./

dr-xr-xr-x 9 root root 0 4月 1 15:48 ../

lrwx------ 1 root root 64 4月 1 15:48 0 -> /dev/pts/22

lrwx------ 1 root root 64 4月 1 15:48 1 -> /dev/pts/22

lrwx------ 1 root root 64 4月 1 15:48 2 -> /dev/pts/22

lr-x------ 1 root root 64 4月 1 15:48 3 -> /home/tocy/project/test.cpp

总结

了解下系统提供的文件操作接口还是不错的,以后遇到问题最起码知道去哪里跟踪。

主要参考:

Linux下文件描述符

http://blog.csdn.net/kumu_linux/article/details/7877770 文件描述符是一个简单的整数,用以标明每一个被进程所打开的文件和socket.第一个打开的 ...

linux下文件描述符的介绍

当某个程序打开文件时,操作系统返回相应的文件描述符,程序为了处理该文件必须引用此描述符.所谓的文件描述符是一个低级的正整数.最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出( ...

&lbrack; 总结 &rsqb; Linux 下文件描述符

1.概述: 文件描述符是内核为了高效管理已被打开的文件所创建的索引.是一个非负整数,用于代指被打开的文件.所有通过I/O操作的系统调用都通过文件描述符. 文件描述符用以表明每一个被进程所打开的文件和s ...

linux 最大文件描述符fd

使用四种框架分别实现百万websocket常连接的服务器 著名的 C10K 问题提出的时候, 正是 2001 年.这篇文章可以说是高性能服务器开发的一个标志性文档,它讨论的就是单机为1万个连接提供服务 ...

Linux Shell 文件描述符 及 stdin stdout stderr 重定向

Abstract: 1) Linux Shell 命令的标准输入.标准输出.标准错误,及其重定位: 2)Linux Shell 操作自定义文件描述符: 文件描述符是与文件相关联的一些整数,他们保持与已 ...

【详解】Linux的文件描述符fd与文件指针FILE&ast;互相转换

使用系统调用的时候用文件描述符(file descriptor,简称fd)的时候比较多,但是操作比较原始.C库函数在I/O上提供了一些方便的包装(比如格式化I/O.重定向),但是对细节的控制不够. 如 ...

Linux的文件描述符

(1).文件描述符的定义 文件描述符是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符:文件描述符是一个简单的非负整数,用以表明每个被进程 ...

对于Linux中文件描述符的疑问以及解决

问题 ​ 每次web服务器或者是几乎所有Linux服务器都需要对文件描述符进行调整,我使用ulimit -n来查看当前用户的最多能打开的文件,默认设置的是1024个,但是系统运行起来以及开启一些简单的 ...

Linux中文件描述符fd和文件指针flip的理解

转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html 简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通 ...

随机推荐

MySQL热备脚本

MYSQL 备份方法:    热备:    http://blog.itpub.net/27099995/viewspace-1295099/    http://blog.csdn.net/dban ...

MyEclipse SVN 插件

一.下载SVN插件subclipse 下载地址:http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 在打开的网 ...

Knockout 是什么?

翻译:Knockout 轻松上手 - 1 Knockout 是什么? 原文名称:KnockoutJS Starter Knockout 是一个非常棒的脚本库,可是我发现许多人并不了解它,所以,思胜翻译 ...

Beta冲刺 第四天

Beta冲刺 第四天 1. 昨天的困难 1.网页使用了一些网上现成的模板,其主要是使用像素做处理的,所以检查起来比较费事费力. 2.使用github代码merge时出现了问题.所以花费了不少的时间在人 ...

寻找复杂背景下物体的轮廓(OpenCV &sol; C&plus;&plus; - Filling holes)

一.问题提出 这是一个来自"answerOpenCV"(http://answers.opencv.org/question/200422/opencv-c-filling-hol ...

Flashbuilder的bug FlashBuilder 1119&colon; 访问可能未定义的属性 on &lpar;通过 static 类型

FlashBuilder 1119: 访问可能未定义的属性 on (通过 static 类型 当此问题出现的时候 无论 刷新 清理 注释 删除 乃至重启电脑都无济于事. 解决方法:备份此类到另外一个地 ...

appium多机并行测试

在实际应用中需要对多个机型并行测试,节省时间 多机测试的思路 启动多个appium server与多台机器交互(android和ios均可)   注意:一定要使用node安装appium的命令行,使用 ...

Android Studio关于USB device not found的解决的方法

Android Studio关于USB device not found的解决的方法 我们使用Android Studio进行Android开发时.当我们使用真机进行调试时.非常可能会出现USB de ...

HBase & thrift & C&plus;&plus;编程

目录 目录 1 1. 前言 1 2. 启动和停止thrift2 1 2.1. 启动thrift2 1 2.2. 停止thrift2 1 2.3. 启动参数 2 3. hbase.thrift 2 3. ...

对特殊字符编码js与c&num;中的处理方法

js: encodeURIComponent();编码 c#: Uri.UnescapeDataString();解码

linux下查看文件描述符,linux下文件描述符的查看及分析相关推荐

  1. linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?

    Linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗? 一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性 3.进程 ...

  2. Linux下多个进程可以同时打开同一个文件吗?文件描述符与打开文件的关系?

    一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性 3.进程可以通过系统调用对文件加锁,从而实现对文件内容的保护 4.任何一个进程删 ...

  3. Linux:centos释放缓存,查看磁盘空间大小,xxx文件夹, 查看文件夹大小,查看剩余内存,查看xxx软件位置,统计某文件夹,统计某文件夹下目录数量,查看文件夹大小,给文件夹下所有的文件赋值权限

    一台老的PHP后台服务器,今天用 free -m 查看,发现内存跑满了. 再 top,然后按下shift+m,也就是按内存占用百分比排序,发现排在第一的进程,才占用0.9%,那是什么占用的呢?谷歌了一 ...

  4. linux中如何看文件换行符,linux下的换行符

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 换行符在不同操作系统下有不同的表示,比如windows下是CR+LF连续两个字符,linux下为了节省空间用LF表示,m ...

  5. linux下查看文件的权限,Linux下查看文件权限、修改文件权限的方法

    查看权限命令查看目录的相关权限可以采用命令ls -lD,或者直接用ls -la 如 ls -l www.jb51.net  //这里表示查看www.jb51.net目录 修改权限命令 chmod 77 ...

  6. 查看linux下文件是否存在,linux中怎么查看文件是否存在

    两个方式:find命令或者shell脚本. 1.find命令 find是linux下用于查找文件的通用方法. find语法: find [指定查找目录] [查找规则] [查找完后执行的action] ...

  7. Linux下,文件权限UGO,ls -l命令的详细查看内容,修改文件文件夹属主属组的命令

    Linux下,用户权限UGO 注意: 1.Linux中的对象都有基本权限UGO,ugo分别表示user,group,other, 2.这里的对象是对文件和文件夹的简写,不是编程语言中的对象概念. 一. ...

  8. 外网访问arm嵌入式linux_嵌入式Linux系统编程——文件读写访问、属性、描述符、API

    Linux 的文件模型是从 Unix 的继承而来,所以 Linux 继承了 UNIX 本身的大部分特性,然后加以扩展,本章从 UNIX 系统接口来描述 Linux 系统结构的特性. 操作系统是通过一系 ...

  9. linux文件描述符与标识符,文件描述符fd

    这里以问答的方式来讨论这个问题: 1. 文件描述符 fd 和文件指针 FILE *的关系? 文件描述符是什么?我们知道每一个进程都有一个自己的PCB(进程控制块),进程控制块的结构是: struct ...

  10. Linux中的文件描述符与打开文件之间的关系

    1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是 ...

最新文章

  1. 在多变环境中长期定位和建图的通用框架
  2. 倒计时1天 | 专属技术人的盛会,为你而来!
  3. Debian,Ubuntu下安装zsh和oh-my-zsh
  4. Oracle数据库日常维护
  5. 我在这里,等你的故事【小废回家看看】
  6. 串口IDLE空闲中断+DMA实现接收不定长数据基于stm32cubemx
  7. java 发送qq消息_php发送qq消息
  8. php时间到期提醒功能,php还剩多长时间过期函数
  9. 一文快速了解oCPX
  10. oracle之数据处理之视图
  11. Qt MQTT安装步骤记录
  12. 20190818:(leetcode习题)反转字符串整数反转
  13. POJ-2034 Anti-prime Sequences dfs
  14. DEM高程数据下载方法
  15. 机器学习之旅:支持向量机通俗导论(理解SVM的三层境界)
  16. 关于原理图库和封装库设计(三)
  17. 提高睡眠质量的东西,这几件东西能让你睡得香又好
  18. find命令的基础用法以及按文件修改时间查找文件
  19. 电子书寻找方法汇总2
  20. 工业强国之路任重道远,制造业乘“疾风”突出重围

热门文章

  1. 微信朋友圈装x代码_微信朋友圈超强装X,电影台词长截图,一键搞定
  2. win10升级补丁_官方win10教育版怎么样
  3. android 键盘 横屏 边框,Android横屏时软键盘全屏问题
  4. Android本地视频压缩方案
  5. 【Unity3D插件】DoTween插件(二)
  6. 钓鱼网站检测技术的演进
  7. LaTex 数学之括号
  8. 连接共享打印机时,弹出无法安装打印机,打印处理器不存在!!
  9. 620集成显卡和mx250,轻薄本的新独显!MX250现身英伟达官网,核显3.5倍性能
  10. PHP生成缩略图、加水印