NDK学习笔记(六)基础:内存管理、标准文件I/O

1.Bionic

Bionic是android平台为使用C和C++进行原生应用程序开发所提供的的POSIX标准C库。

Bionic提供C标准库宏、类型定义、函数、android特有的特性。
特性:

  • 内存管理
  • 文件输入输出
  • 字符串操作
  • 数学
  • 日期和时间
  • 进程控制
  • 信号处理
  • 网络套接字
  • 多线程
  • 用户和组
  • 系统配置
  • 命名服务切换

2.C语言的动态内存管理

#include <stdlib.h>//需要此库
void * malloc(int size)

//申请内存
    int *a = (int *) malloc(sizeof(int) * 16);
//释放内存
void free(void* memory);
//为了避免意外使用无效指针,最好在释放后置NULL
a=NULL;
//根据新的内存大小来扩展或者缩小
//如果重新分配成功,返回重新分配的指针;失败,则保留原来的动态内存分配不变并返回NULL。
a =(int *) realloc(a, sizeof(int) * 10);

3.C++的动态内存管理

使用new 申请动态内存

//单个元素的动态内存分配
int *m = new int;
//多个元素的动态内存分配
int *mm = new int[10];

使用delete来释放内存

    delete m;
    delete[] mm;

通过malloc分配的内存块必须用free关键字释放。
通过new关键字分配的内必须由相应的delete关键字释放。

4.标准文件I/O

标准C库提供了两种文件I/O
低级I/O:原始的I/O函数,更加适合处理数据流。
流I/O:更高级别的、可缓冲的I/O函数、更适合处理数据流。
(1)标准流

  • stdin:应用程序标准输入流
  • stdout:引用程序标准输出流
  • stderr:应用程序标准错误流

(2)写入流

//打开流
    FILE *f = fopen("/sdcard/Download/test.txt", "w");
    if (f == NULL) {
      //没有打开,返回NULL指针
    } else {
      //与流交互
      
    }

写入数据

        char c[] = {'c', 'a', '\n'};
        int count = sizeof(c) / sizeof(c[0]);
		//fwrite返回实际写入流的元素个数
        if(count != fwrite(c, sizeof(char),count,f)){
            //出现错误
        }
        fclose(f);
		//如果不能写入,则返回EOF
        if (EOF == fputs("hello", f)) {
            //出现错误
        }
        fclose(f);

向流写入单个字符

        char c = 'a';
        //如果字符不能被写入流,则fputc函数返回EOF,否则,返回字符本省。
        if (c != fputc(c, f)) {
            //出现错误
        }
        fclose(f);

向流中的写入有格式的数据

		//fprintf返回写入流的字符个数,出错的情况下,返回一个负数
        int code = fprintf(f, "The %s is %d", "number", 2);
        if (0 <code) {
            //错误
        }
        fclose(f);

刷新缓冲区
在一下情况下会自动刷新缓冲区:

  • 引用程序正常终止
  • 在行缓冲时写入新行
  • 当缓冲区已满
  • 当流被关闭

手动刷新缓冲区

        fprintf(f, "The %s is 123", "number");
        //如果缓冲区不能写入,fflush函数返回EOF;否则返回0
        fflush(f);

(3)读取流

        char buff[5];
        int count = 4;
        //读取count个sizeof(char)大小的元素放入缓冲区buff
        //返回实际读取的元素个数
        if (count != fread(buff, sizeof(char), count, f)) {
            //错误
        }

读取字符序列

        char buff[1024];
        if (NULL == fgets(buff,1024,f)) {
            //错误
        }else{
            __android_log_print(ANDROID_LOG_INFO, "buff", "%s", buff);
        }

读取单个字符

        int result;
        result = fgetc(f);
        if (EOF == result) {
			//错误
        } else {
            unsigned char ch = (unsigned char) result;
            __android_log_print(ANDROID_LOG_INFO, "test", "%c", ch);
        }

从流中读取格式数据

        char s[5];
        int i;
        //读取成功,返回读取的项目个数;若有错误,则返回EOF
        if (2 != fscanf(f, "The %s is %d", s, &i)) {
			//错误
        }
        __android_log_print(ANDROID_LOG_INFO, "123321", "%s%d", s, i);

检查文件结尾

        char buff[1024];
        //文件到达末尾返回一个非零值;如果可以从流中读取更多数据,则返回零。
        while (0 == feof(f)) {

            fgets(buff, 1024, f);
            __android_log_print(ANDROID_LOG_INFO, "123321", "%s", buff);
        }

搜索位置

int fseek(FILE *stream,long offset,int whence);
offset:相对偏移量
whence:
	SEEK_SET:偏移量相对于流的开头
	SEEK_CUR:偏移量相对于当前位置
	SEEK_END:偏移量相对于流结尾
        fputs("123456", f);
        fseek(f, -6, SEEK_CUR);
        fputs("654321", f);
        fflush(f);

错误检查

ferror(FILE* stream )

关闭缓冲流

flose(FILE* stream)

if(0 != fclose(f)){
//错误可能是磁盘空间不足,缓冲的输出不能写入到流中
}

5.与进程交互

(1)执行shell命令

        int result;
        result = system("mkdir /data/data/com.example.testnt/test");
        if (-1 == result || 127 == result) {
           //执行失败
        }

在这里插入图片描述
(2)与子进程通信

FILE *popen(const char* command,const char* type);
int pclose(FILE* stream);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值