美文网首页
NDK基础(三)——流IO

NDK基础(三)——流IO

作者: 王志强_9380 | 来源:发表于2020-06-29 15:14 被阅读0次

文件读写

打开文件fopen

FILE *stream = fopen(filePath, "w");

第二个参数是打开模式:
r:只读模式,文件必须存在
w:只写模式,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则创
a:以附加模式打开文件,只能写,新输出的内容会加在文件结尾,如果文件不存在,创建文件
r+:读写模式,文件必须存在
w+:读写模式,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则创建
a+:附加读写模式,读的时候在文件头,写的时候在文件尾。文件不存在,则会创建

注意:以双模打开文件(即:r+,w+,a+),读写转换之前应该用fflush刷新缓冲区

写文件

extern "C"
JNIEXPORT void JNICALL
Java_com_example_ffmpegapplication_NativeStudy_IOStreamWriteTest(JNIEnv *env, jobject instance,
                                                            jstring filePath_) {
    const char *filePath = env->GetStringUTFChars(filePath_, 0);
    // TODO
    FILE *stream = fopen(filePath, "w");
    if (stream == NULL) {
        LOGE("%s", "文件打开失败");
        return;
    }
    //=========================写文件=====================================
    //写入数据块
    char data[6] = {'h', 'e', 'l', 'l', 'o', '\n'};
    if (sizeof(data) == fwrite(data, sizeof(char), sizeof(data), stream)) {
        LOGE("%s", "fwrite写入成功");
    }

    //写入字符序列
    const char *datas = "fputstest\n";
    if (EOF != fputs(datas, stream)) {
        LOGE("%s", "fputs写入成功");
    }
    //写入单个字符
    char c = 'D';
    if (c == fputc(c, stream)) {
        LOGE("%s", "fputc写入成功");
    }

    //写入有格式的数据
    if (fprintf(stream, "this %s is %d \n", "number", 2) >= 0) {
        LOGE("%s", "fprintf写入成功");
    }

    //刷新缓冲区
    if (EOF != fflush(stream)) {
        LOGE("%s", "fflush写入成功");
    }

    if(0 == fclose(stream)){
        LOGE("%s","文件关闭成功");
    }
    env->ReleaseStringUTFChars(filePath_, filePath);
}

最终结果:

hello
fputstest
Dthis number is 2 
方法 作用 例子 成功的返回值
fwrite 写入数据块 fwrite(data, sizeof(char), sizeof(data), stream) sizeof(data)
fputs 写入字符序列 fputs(datas, stream) != EOF
fputc 写入单个字符 fputc(c, stream) c
fprintf 写入有格式的数据 fprintf(stream, "this %s is %d \n", "number", 2) >= 0

格式说明符:
%d:将整数参数格式化为有符号十进制数
%u:将无符号整数格式化为无符号十进制数
%o:将无符号整数格式化为八进制数
%x:将无符号整数格式化为十六进制数
%c:将整数参数格式化为单个字符
%f:将双精度参数格式化为浮点数
%e:将双精度参数格式化为固定格式
%s:打印给出的NULL结尾字符数组
%p:打印给出的指针作为内存地址
%%:写入一个%字符

刷新缓冲区fflush

以下情况会自动刷新缓冲区:
应用程序正常终止
在行缓冲时写入新的行
缓冲区已满
流被关闭

读文件


extern "C"
JNIEXPORT void JNICALL
Java_com_example_ffmpegapplication_NativeStudy_IOStreamReadTest(JNIEnv *env, jobject instance,
                                                                 jstring filePath_) {
    const char *filePath = env->GetStringUTFChars(filePath_, 0);
    // TODO
    FILE *stream = fopen(filePath, "r");
    if (stream == NULL) {
        LOGE("%s", "文件打开失败");
        return;
    }
    //=========================读文件=====================================
    //读取块数据
    char buffer[5];
    if (4 == fread(buffer, sizeof(char), 4, stream)) {
        LOGE("%s%s", "fread读取成功:", buffer);
    }

    //读取字符序列
    char bufferstr[5];
    while (0 == feof(stream)) {
        if (NULL != fgets(bufferstr, 5, stream)) {
            LOGE("%s%s", "fgets读取成功:", bufferstr);
        } else {
            break;
        }
    }

    fseek(stream, 10, SEEK_SET);

    //读取单个字符
    unsigned char ch;
    int result = fgetc(stream);
    if(EOF != result) {
        ch = (unsigned char)result;
        LOGE("%s%c","fgetc读取成功:",ch);
    }

    fseek(stream, -18, SEEK_END);
    //读取格式数据
    char s[5];
    int i;
    if(2 == fscanf(stream, "this %s is %d", s, &i)) {
        LOGE("%s%s %d","fscanf读取成功:",s,i);
    }

    if(0 != ferror(stream)) {
        LOGE("%s","前一次请求发生错误");
    }

    if(0 == fclose(stream)){
        LOGE("%s","文件关闭成功");
    }
    env->ReleaseStringUTFChars(filePath_, filePath);
}

打印:

01-20 11:09:15.832: E/www(30334): fread读取成功:hell� I��
01-20 11:09:15.832: E/www(30334): fgets读取成功:o
01-20 11:09:15.832: E/www(30334): fgets读取成功:fput
01-20 11:09:15.832: E/www(30334): fgets读取成功:stes
01-20 11:09:15.832: E/www(30334): fgets读取成功:t
01-20 11:09:15.832: E/www(30334): fgets读取成功:Dthi
01-20 11:09:15.832: E/www(30334): fgets读取成功:s nu
01-20 11:09:15.832: E/www(30334): fgets读取成功:mber
01-20 11:09:15.832: E/www(30334): fgets读取成功: is 
01-20 11:09:15.832: E/www(30334): fgets读取成功:2 
01-20 11:09:15.832: E/www(30334): fgetc读取成功:s
01-20 11:09:15.832: E/www(30334): fscanf读取成功:number 2
01-20 11:09:15.833: E/www(30334): 文件关闭成功

方法 作用 例子 成功的返回值
fread 读取块数据 fread(buffer, sizeof(char), 4, stream) 需要读取的字符数(4)
fgets 读取字符序列 fgets(bufferstr, 10, stream) != NULL
fgetc 读取单个字符 fgetc(stream) != EOF
fscanf 读取格式数据 fscanf(stream, "this %s is %d", s, &i) 读取的项目个数(2)
  • 上面的例子中,fgets我们传入的是每次读取5个字符,结果显示只有4个,是因为,每次读取字符数减1,再加上换行符
  • 在读取文件流的时候,如果已经设置了流文件的结束指示符,可以用feof函数检查
  • fseek,修改流中的位置。最后一个参数:
    SEEK_SET:偏移量相对于流开头
    SEEK_CUR:偏移量相对于当前位置
    SEEK_END:偏移量相对于流结尾
    上面的例子中
    fseek(stream, 10, SEEK_SET):从开头往后跳过10个字符,是字符s
    fseek(stream, -18, SEEK_END):从结尾往前跳18个字符,是this number is 2 ,要加上换行符和空格

相关文章

  • NDK基础(三)——流IO

    文件读写 打开文件fopen 第二个参数是打开模式:r:只读模式,文件必须存在w:只写模式,若文件存在则文件长度清...

  • java基础之IO流

    IO流上:概述、字符流、缓冲区(java基础) IO流结构图 FilterInputStream、FilterOu...

  • 2018-10-10

    掘金50道基础 io流案例

  • Java基础之IO流(三)!!

    转换流 顾名思义,就是可以把字符与字节的流相互转换 OutputStreamWriter类 OutputStrea...

  • java IO入门笔记

    1.java IO流的概念,分类,类图 1.1. java IO 流的概念 java的io是实现输入和输出的基础,...

  • Java IO详解

    1 Java IO流的概念,分类 1.1 Java IO流的概念 java的IO是实现输入和输出的基础,可以方便的...

  • Java基础之IO流

    ##Java基础之IO流IO流常用几个类的关系如下: 字节流 字节输入流FileInputStream 读取文件用...

  • Java基础-IO流-网络IO

    Java工程师知识树[https://www.jianshu.com/p/db77d19a25f6] / Ja...

  • 2019-02-27

    基于IO流基础总结 io解说: 按照流动的方向,以内存为基准,分为 输入input 和 输出 output ,即流...

  • Java基础——流(IO)

    流(Stream)——水流 ,可以理解为连接文件和程序的东西,Stream是从起源(source)到接收(sink...

网友评论

      本文标题:NDK基础(三)——流IO

      本文链接:https://www.haomeiwen.com/subject/gqecbctx.html