文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换

文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换

转载于糨糊的专栏

最近在linux下编程常需要对一些文件进行操作。有时不同的条件下,需要将文件指针/句柄(FILE*)、文件描述符(fd)以及文件路径(filepath)进行相互转换,以满足实际的编程需要。

现简单的做一下整理。如下。

 

 

1:文件路径 文件描述符应是唯一的。文件指针(值)不是唯一的,但指向的对象也应该是唯一的。
2: FILE*中包含fd的信息,而且还包含IO缓冲,所以可以理解为FILE*是对fd的封装,是C的标准形式,所以FILE*比fd更适合跨平台,应多用fopen,少用 open。

 

3:转换

   文件路径 到 文件指针:filepath --fopen()-->FILE*;
   文件路径 到 文件描述符:filepath--open()--fd;

 

   文件描述符 到 文件指针:fd--fdopen()-->FILE*;
   文件描述符 到 文件路径:fd--readlink(/proc/%getpid()/fd/%fd"))-->filepath; //这属于“曲线救国”

   文件指针 到 文件描述符:FILE*--fileno()--->fd;
   文件指针 到 文件路径:FILE* --- ??? ---PATH;// 这个的直接转换的方法还没有查到。请补充。



评注:

根据pid和fd的值获取打开文件的路径这办法很有用,Android系统中内存的进程间传递用了该方法。

void *aenc_thread_func2(void *data) { int ret; struct test_resource *res = (struct test_resource *)data; AUDIO_STREAM_S stream_audio; struct timeval timeout_val; fd_set read_fds; XMEDIA_S32 aenc_fd; XMEDIA_S32 chn_num; aenc_fd = XMEDIA_API_AENC_GetFd(res->aenc_chn); if (aenc_fd < 0) { DEMO_PRINT("XMEDIA_API_AENC_GetFd failed with %#x!\n", aenc_fd); return NULL; } if (res->venc_snap == XMEDIA_TRUE) { chn_num = res->venc_chn_num - 1; } else { chn_num = res->venc_chn_num; } while (res->aenc_thread_run) { FD_ZERO(&read_fds); FD_SET(aenc_fd, &read_fds); timeout_val.tv_sec = 1; timeout_val.tv_usec = 0; ret = select(aenc_fd + 1, &read_fds, NULL, NULL, &timeout_val); if (ret < 0) { DEMO_PRINT("select failed!\n"); break; } else if (ret == 0) { DEMO_PRINT("get aenc stream time out, exit thread\n"); continue; } else { if (FD_ISSET(aenc_fd, &read_fds)) { ret = XMEDIA_API_AENC_GetStream(res->aenc_chn, &stream_audio, XMEDIA_FALSE); if (ret != XMEDIA_SUCCESS) { DEMO_PRINT("XMEDIA_API_AENC_GetStream(%d), failed(0x%x)!\n", res->aenc_chn, ret); return NULL; } if (res->save_mode == 1) { /* save audio stream to file */ (XMEDIA_VOID) fwrite(stream_audio.pStream, 1, stream_audio.u32Len, res->fd_for_mic[0]); } else if (res->save_mode == 0) { for (int i = 0; i < chn_num; i++) { app_liveserver_send_audio_data(i, res->aenc_type, &stream_audio); } } /* finally you must release the stream */ ret = XMEDIA_API_AENC_ReleaseStream(res->aenc_chn, &stream_audio); if (ret != XMEDIA_SUCCESS) { DEMO_PRINT("%s: XMEDIA_API_AENC_ReleaseStream(%d), failed(0x%x)\n", __FUNCTION__, res->aenc_chn, ret); return NULL; } } } } return NULL; } XMEDIA_S32 video_chn_request_key_frame(xcam_handle venc_handle, xcam_void *param) { VENC_CHN venc_chn; XMEDIA_S32 ret; venc_chn = (VENC_CHN)venc_handle; ret = XMEDIA_API_VENC_RequestIDR(venc_chn, XMEDIA_TRUE); // 请求IDR帧 第二个参数代表使能立刻解码IDR帧 if (XMEDIA_SUCCESS != ret) { DEMO_PRINT("VENC_RequestIDR(chn:%d) faild with%#x!\n", venc_chn, ret); return XMEDIA_FAILURE; } else { DEMO_PRINT("VENC_RequestIDR(chn:%d) successful!\n", venc_chn); } return ret; } void save_init(struct test_resource *res) { XMEDIA_S32 ret; XMEDIA_S32 i; char save_file[256] = {0}; XMEDIA_S32 chn_num; if (res->venc_snap == XMEDIA_TRUE) { chn_num = res->venc_chn_num - 1; } else { chn_num = res->venc_chn_num; } if (res->save_mode == 1) { XMEDIA_U32 width = 0; XMEDIA_U32 height = 0; for (i = 0; i < chn_num; i++) { memset(save_file, 0, sizeof(save_file)); if (i == 0) { width = res->big_image_size.u32Width; height = res->big_image_size.u32Height; } else if (i == 1) { width = res->small_image_size.u32Width; height = res->small_image_size.u32Height; } else { width = res->ai_image_size.u32Width; height = res->ai_image_size.u32Height; } snprintf(save_file, 256, "%s%d_%d.%s", res->save_path, width, height, payload_to_string(res->venc_payload[i])); res->esfile[i] = fopen(save_file, "wb"); } if (res->audio_enable == XMEDIA_TRUE) { memset(save_file, 0, sizeof(save_file)); snprintf(save_file, 256, "%saudio%d.%s", res->save_path, res->aenc_chn, payload_to_string(res->aenc_type)); res->fd_for_mic[0] = fopen(save_file, "wb"); } } else if (res->save_mode == 0) { ret = app_liveserver_init(); CHECK_RET_SUCCESS(ret); } for (i = 0; i < chn_num; i++) { if (res->save_mode == 0) { xcam_track_video_source_info track_video; xcam_track_audio_source_info track_audio; xcam_handle aenc_handle = -1; if (res->audio_enable == XMEDIA_TRUE) { aenc_handle = 0; } app_liveserver_get_video_src_info(i, res, &track_video); // 获取视频源信息 app_liveserver_get_audio_src_info(aenc_handle, res, &track_audio); // 获取音频源信息 ret = (i, &track_video, aenc_handle, &track_audio, (const xcam_char *)g_stream_name[i], video_chn_request_key_frame); // 添加流至liveserver中 video_chn_request_key_frame->请求关键帧 if (ret != XMEDIA_SUCCESS) { printf("Liveserver add stream venc_handle[%u] failed! \n\n", i); return; } } } return; } void save_deinit(struct test_resource *res) { XMEDIA_S32 i; XMEDIA_S32 chn_num; if (res->venc_snap == XMEDIA_TRUE) { chn_num = res->venc_chn_num - 1; } else { chn_num = res->venc_chn_num; } if (res->save_mode == 1) { for (i = 0; i < chn_num; i++) { fclose(res->esfile[i]); } fclose(res->fd_for_mic[0]); } else if (res->save_mode == 0) { app_liveserver_deinit(); } return; } // static int16_t linear_interpolate(int16_t y1, int16_t y2, float t) { // return y1 + (int16_t)((y2 - y1) * t); // } // static void resample_8000_to_16000(int16_t *src_samples, int src_length, int16_t *dst_samples) { // int i; // int dst_length = src_length * 2; // for (i = 0; i < src_length - 1; i++) { // dst_samples[i * 2] = src_samples[i]; // 原始采样点 // dst_samples[i * 2 + 1] = linear_interpolate(src_samples[i], src_samples[i + 1], 0.5); // 插值点 // } // // 处理最后一个采样点 // dst_samples[(src_length - 1) * 2] = src_samples[src_length - 1]; // dst_samples[(src_length - 1) * 2 + 1] = src_samples[src_length - 1]; // } void play_audio_file(char *filepath) { printf("[%s]open %s\n", __func__, filepath); XMEDIA_S32 ret; // struct test_resource *p_t = (struct test_resource *)arg; XMEDIA_S32 adec_chn = g_adec_chn; printf("into play_audio_file adec_chn %d \n", (int)adec_chn); AUDIO_STREAM_S stream; int audio_play_file = 1; #if USE_XY == 1 // PCM 2 AAC XMEDIA_U32 len = 320; #else XMEDIA_U32 len = 640; #endif XMEDIA_U32 read_len = 0; XMEDIA_U8 *audio_stream = NULL; // XMEDIA_S32 adec_chn = p_t->adec_chn; // adec_chn audio_stream = (XMEDIA_U8 *)malloc(sizeof(XMEDIA_U8) * len * 2); if (NULL == audio_stream) { printf("%s: malloc failed!\n", __FUNCTION__); return NULL; } FILE *audio_fp = NULL; int play_flag = 0; long filesize = 0; long count_audio_len = 0; while (1) { stream.pStream = audio_stream; // 1.获取文件并输出 // 进行操作 // a.打开音频文件 // printf("into audio_fp\n"); if (play_flag == 0) { printf("into play_speaker:play_flag = 0\n"); audio_fp = fopen(filepath, "rb"); if (audio_fp == NULL) { perror("open audio.pcm failed\n"); continue; } fseek(audio_fp, 0, SEEK_END); // 移动到文件末尾 filesize = ftell(audio_fp); // 获取当前位置,即文件大小 printf("文件 '%s' 的大小是 %ld 字节。\n", filepath, filesize); play_flag = 1; fseek(audio_fp, 0, SEEK_SET); continue; } else { // printf("into play_speaker:play_flag = 1\n"); // read_len = fread(stream.pStream, 1, len*2, audio_fp); // printf("准备读取的 len*2 = %d\n", len*2); // printf("当前文件位置:%ld\n", ftell(audio_fp)); // printf("stream.pStream 地址: %p\n", (void*)stream.pStream); read_len = fread(stream.pStream, 1, len * 2, audio_fp); if (ferror(audio_fp)) { perror("读取文件时发生错误"); clearerr(audio_fp); } if (read_len > 0) { stream.u32Len = read_len; count_audio_len += read_len; // printf("此次读取了 %ld 字节,总共读取了 %ld 字节。\n", read_len, count_audio_len); if (count_audio_len >= filesize) { count_audio_len = 0; play_flag = 0; printf("播放结束\n"); fclose(audio_fp); audio_fp = NULL; ret = XMEDIA_API_ADEC_SendEndOfStream(adec_chn, XMEDIA_FALSE); if (XMEDIA_SUCCESS != ret) { AUDIO_ERR("%s: XMEDIA_API_ADEC_SendEndOfStream failed(0x%x)\n", __FUNCTION__, ret); } break; } } else { printf("无数据或错误,可能已到文件末尾\n"); } } if (read_len <= 0) { continue; } stream.u32Len = read_len; ret = XMEDIA_API_ADEC_SendStream(adec_chn, &stream, XMEDIA_TRUE); if (XMEDIA_SUCCESS != ret) { AUDIO_ERR("%s: XMEDIA_API_ADEC_SendStream(%d) failed(0x%x)\n", __FUNCTION__, adec_chn, ret); break; } } if (audio_fp != NULL) { fclose(audio_fp); } if (audio_stream != NULL) { free(audio_stream); } } // TODO 音频解码 void *adec_thread_func2(void *arg) { XMEDIA_S32 ret; struct test_resource *p_t = (struct test_resource *)arg; AUDIO_STREAM_S stream; #if USE_XY == 1 // PCM 2 AAC XMEDIA_U32 len = 320; #else XMEDIA_U32 len = 640; #endif XMEDIA_U32 read_len = 0; XMEDIA_U8 *audio_stream = NULL; XMEDIA_S32 adec_chn = p_t->adec_chn; // adec_chn audio_stream = (XMEDIA_U8 *)malloc(sizeof(XMEDIA_U8) * len * 2); if (NULL == audio_stream) { printf("%s: malloc failed!\n", __FUNCTION__); return NULL; } while (p_t->adec_thread_run) { /* read from file */ stream.pStream = audio_stream; QrcodePacket *p = (QrcodePacket *)que_pop(g_que_r); if (!p) { printf("packet is null\n"); exit(0); } read_len = p->dat1; #if USE_XY == 1 // static long i = 0; // if (!(i++ % 100)) // { // printf("|read_len = %d\n", read_len); // /* code */ // i -= 100; // } // PCM 2 AAC // 传入8000Hz 但需要传出16000 #endif // int16_t dst_samples[320]; // // 调用重采样函数 // resample_8000_to_16000(p->address, read_len, dst_samples); memcpy(stream.pStream, p->address, read_len); int nty = 0; nty = p->dat2; if (nty == 99) { pool_push(g_pPool_r, (void *)p); break; } pool_push(g_pPool_r, (void *)p); if (read_len <= 0) { /* ret = XMEDIA_API_ADEC_SendEndOfStream(adec_chn, XMEDIA_FALSE); if (XMEDIA_SUCCESS != ret) { AUDIO_ERR("%s: XMEDIA_API_ADEC_SendEndOfStream failed(0x%x)\n", __FUNCTION__, ret); } */ continue; } stream.u32Len = read_len; // #if USE_XY == 1 // //PCM 2 AAC // #else // stream.u32Len = read_len/2; // #endif // printf("adec_thread_func2 ---------------%d\n", (int)stream.u32Len); ret = XMEDIA_API_ADEC_SendStream(adec_chn, &stream, XMEDIA_TRUE); if (XMEDIA_SUCCESS != ret) { AUDIO_ERR("%s: XMEDIA_API_ADEC_SendStream(%d) failed(0x%x)\n", __FUNCTION__, adec_chn, ret); break; } if (!(p_t->adec_thread_run)) { XMEDIA_API_ADEC_DestroyChn(adec_chn); break; } } if (audio_stream != NULL) { free(audio_stream); } } 注释一下代码
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值