• C语言读取Java的字节码文件的第一步


    最近学习C语言,想用C语言写一个字节码解析器,而需要解析字节码文件,首先需要了解C语言是怎么以二进制形式读取文件的。

    一、先上示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #define N 5
    
    int main() {
    	FILE* file;
    	int i, b[N], elemSize=sizeof(int);
    	
    	if ((file= fopen("F:\\gitcode\\gitee\\ziyu-learn-jvm-java\\target\\classes\\com\\ziyu\\example\\HelloWorld.class", "rb+"))==NULL) //以返回值fpl判断是否打开成功,如果为NULL表示失败
    	{
    		printf ("Failed to open the file !\n");
    		exit (0) ; //终止程序,stdlib .h 头文件中
    	}
    
    	printf("Succeed to open the file.\n");
    
    	fread(b, elemSize, N, file);
    
    	//在屏幕上显示数组b的内容
    
    	for(i=0; i<N; i++){
    		printf("%08X ", b[i]);
    	}
    	fclose(file);
    	return 0;
    }
    

    二、代码解析

    2.1 stdio.h

    读取和写入文件,以及从控制台获取数据和用控制台打印信息,都需要先引入 stdio.h 这个头文件:

    #include <stdio.h>
    

    所以,以下函数都来自该头文件:

    2.2 stdlib.h

    在这个例子中,之所以要引用 C语言标准库,主要是因为用到了 exit 函数。这个函数就是来自于 stdlib.h 头文件。

    2.3 define

    关于这个 #define宏定义,我在编写代码时还犯了个错误,那就是结尾不能有;,否则编译时会提示在其他行有语法错误。

    2.4 fopen

    它的用法为:

    FILE *fopen(char *filename, char *mode);
    
    • 函数的第一个参数filename为文件名(包括文件路径);
    • 函数的第二个参数mode为打开方式;

    最基本的文件打开方式有以下几种:

    打开方式 描述 如果文件不存在时 如果文件存在时
    "r" 以“只读”方式打开文件 打开失败 打开成功,但是只允许读取,不允许写入
    "w" 以“写入”方式打开文件 创建一个新文件 清空原有的文件内容,写入的数据从头开始加入文件
    "a" 以“追加”方式打开文件 创建一个新文件 保留原有的文件内容,写入的数据追加到文件的末尾

    如果加上 + 之后呢?

    打开方式 变化 如果文件不存在时 如果文件已存在时
    "r+" 支持写入 打开失败 打开成功,允许读取和写入
    "w+" 支持读取 创建一个新文件 清空原有的文件内容,写入的数据从头开始加入文件
    "a+" 支持读取 创建一个新文件 保留原有的文件内容,写入的数据追加到文件的末尾

    观察对比之后发现:

    1. 当文件存在或者不存在时,"r+"/"w+"/"a+" 的处理方式和对应的 "r"/"w"/"a" 保持一致;
    2. + 相当于让 "r"/"w"/"a" 同时支持读和写;

    fopen 返回 NULL 时,就表示文件打开失败了。

    2.5 fread

    fread() 函数用来从指定文件中读取块数据。

    fread() 的原型为:

    size_t fread ( void *dstBuf, size_t elemSize, size_t count, FILE *fp );
    

    我们来分析一下四个参数:

    参数名称 说明 描述
    dstBuf 目标内存区块的指针 它可以是数组、变量、结构体等。fread() 中的 dstBuf 用来存放读取到的数据
    elemSize 表示每个数据块的字节数 单位大小。如果dstBuf是数组,elemSize就是数组元素的字节数
    count 表示要读写的数据块的块数 数量
    fp 表示文件指针 就是 fopen 打开的文件指针

    2.6 fclose

    文件一旦使用完毕,应该用 fclose() 函数把文件关闭,以释放相关资源,避免数据丢失。fclose() 的用法为:

    int fclose(FILE *fp);
    
    • 函数参数 fp 为文件指针
    • 文件正常关闭时,fclose() 的返回值为0,如果返回非零值则表示有错误发生。

    所以正常的使用应该遵循:

    // 打开文件
    FILE* fp = fopen(...);
    
    // 读取或写入文件
    fread(fp);
    fwrite(..., fp);
    
    // 关闭文件
    fclose(fp);
    
  • 相关阅读:
    uniq命令
    全局滚动条样式美化
    感受一下Java乱码出现就知道怎么解决Java乱码了
    用于注解解析的工具类
    迅为i.MX8MM开发板资料更新啦!Linux安卓9.0工业核心板
    迅为-IMX6Q开发板Buildroot文件系统nfs测试
    进步一点点丨迅为4412开发板Linux内核开发基础
    迅为RK3399开发板运行第一个Android程序
    每天学习一点丨借助U盘或TF卡拷贝程序到迅为IMX6ULL开发板上(二)
    资料完整丨i.MX6Q开发板ARM恩智浦工业级linux安卓系统迅为iMX6Q/DL Plus板
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/15766302.html
Copyright © 2020-2023  润新知