Hadoop的Mapper是怎么从HDFS上读取TextInputFormat数据的

Hadoop的Mapper是怎么从HDFS上读取TextInputFormat数据的,第1张

Hadoop的Mapper是怎么从HDFS上读取TextInputFormat数据

Hadoop中控制文件格式,split方式和record读取方式的类都继承自InputFormat这个抽象类。比如实现每次读取文本文件一行的就是TextInputFormat,这个类进一步使用LineRecordReader进行实际的读取 *** 作。以Hadoop 101为例,在LineRecordReader第97-99行:

newSize = inreadLine(value, maxLineLength,

Mathmax((int)Mathmin(IntegerMAX_VALUE, end-pos),

maxLineLength));

从文本行读取类LineReader in中读取一行写入record的value中。为了一次读取两行,可以将96-106行的while循环再复制粘贴一份在下面。

但是LineReader的readLine函数执行时会首先将value原来的值清空,但是我们读取第二行时不想将第一行的内容清空。因此对LineReader的readLine函数做一点修改:

为了保留原来的readLine函数,我们首先讲这个函数复制粘贴一份在下面,将readLine的函数声明做一点修改,增加是否clear value的判断:

public int readLine(Text str, int maxLineLength,

int maxBytesToConsume, boolean clear) throws IOException {

然后讲123行的strclear();修改为if (clear) {strclear();}

这样,在LineRecordReader的两个while循环中,第一次readLine应为:

newSize = inreadLine(value, maxLineLength,

Mathmax((int)Mathmin(IntegerMAX_VALUE, end-pos),

maxLineLength), true);

光驱是怎么读取数据的?

你好!很高兴解答你的提问!请你阅读如下提示,排除烦恼。谢谢!

1,光盘放进光盘,夹盘器夹紧光盘,主轴电机带着旋转到一定转数,司服电机推激光头车到近盘心。

2,开激光单元发射激光束照射到光盘反光区最近心圈,探测光盘类型与寻地方式,根据反射回的光

3,束的抖动变化,转换为二进制数据,由译码器变成光驱能读的数据,传递给电脑中央处理器处理。

4,光驱解读出光盘内侧的光盘核心引导数据,确定光盘类型与播放模式,数据头与尾,文件系统。

5,数据排列结构,确定读取光盘形式。从光盘读取到的数据可以是资料,文件,,音乐,影片,

6,命令。光盘的微观结构是螺旋形的,象夏天点的蚊香,密密麻麻排列着肉眼看不见的光轨存数据。

7,顺序读取光盘数据时,激光头沿光盘弦线从内到外作直线运动,完成从内到外读取螺旋形光轨。

8,正好跟蚊香燃烧的顺序相反。最重要的核心数据都在光盘近心圈,所以刮伤近心圈,整盘读不出。

9,就是这个原因,因为引导如何读取光盘的数据都在近心圈,外圈基本存储普通数据,损失小点。

10,如果跳来跳去读光盘数据,就会参照光盘近心圈的导引数据,寻址到真实数据存在的光轨位置。

11,然后读取到所需数据,这样激光头小车就会移来移去发出响声。光盘从内圈到外圈的周长不同,

12,中心圈最短,最外圈最长。每一圈可容纳的数据也是如此,近中心最少,最外圈最多,这样会

13,导致光驱读取到数据的速度会变化,如果为了保持读取数据速度的恒定,就得调节主轴电机的

14,转数,读内圈时要转得快,激光头小车也要移得快,外圈要转得慢,激光头小车也要移得慢。

15,所以我们会听到光盘转动的风噪会有变化,尤其是跳来跳去读存在光盘不同区域的数据时,

16,风噪都会听出区别。当光盘有刮伤时,由于有数据损坏缺失,导致光驱读不下去,于是就会

17,跳回来继续读取,实在读不出原数据,就用CRC32数据冗余机制,加速读取上一段与下一段

18,区域的数据,进行纠错或预测判断来填补缺失的数据,于是主轴电机转速更高,反复读取的

19,风噪就更明显,时快时慢,就是光驱试图通过调节速度来读出数据。光盘记录数据宏观来说

20,是光轨,微观来说,每一位数据都是以物理形式记录的。通常激光在平整的光盘染料面烧蚀

21,出一小坑,代表数据1,而没被烧出坑来的地方就是一小个平面,代表数据0,激光从一个固定

22,的角度入射进坑,与入射到平台,激光的反射与折射的角度与轨迹会发生明显不同。最后回

23,到激光头后,会被折射到光敏元件上,由光信号转换为电脉冲信号,传递给光驱里的译码器。

24,译码器再转换为电脑能识别的资料或命令。光轨就是这样由这样密密麻麻排列的凹坑与平台

25,组成。众多的光轨再排列组成光盘。电脑是处理二进制数据的机器,磁盘,U盘无一不是二进

26,制存储数据的。硬盘是利用磁性原理,有磁无磁代表有无数据。磁极排列走向决定数据0或1。

27,内存利用电容器的电位高低来判断数据0或1,有电无电来判断有无数据。数据总线是以脉冲

28,波的波峰波谷来判断数据0或1,没脉冲波没数据,有脉冲波有数据。闪存也是利用存储单元的

29,电位高低来判断数据0或1,有电势有数据,没电势没数据。人脑的高级指令都得译成机器语言。

30,我们以10进制为计算单位,电脑能接受的数据都是二进制的,所以编程员的工作很辛苦且枯燥。

stm32 是怎么读取串口数据的

串口接收中断,接收数据,再判断命令,根据命令的不同来确定下面的 *** 作

*** 作系统是怎么读取硬盘数据的?

首先CPU向内存要数据,内存得到指令后向硬盘要数据,硬盘把数据交给内存,内存再交给CPU处理。

plc的主站、从站是怎么从DIO、AIO模块读取或发送数据的

以西门子为例:

PPI通信直接将主从的IO或V区进行通信,可以将AIO的数据放在V存储区中做通信。 例如:将主站IB0数据直接传送到从站QB0。或者主站VB0数据传送到从站VB0当中,做数据交流。

MODBUS通信直接通信V存储区。

读取尺子上的数据的读取用日语怎么说

読み出す 日よみだす

[动]读出,读取

等于 read out

1〔読み始める〕begin to read

2〔コンピュータ内の记忆データを取り出す〕retrieve ((data))

hadoop mapper类 切割数据的时候怎么根据回车切割

DataTable dt = new DataTable();

dtColumnsAdd(new DataColumn("PreRevDate0", typeof(decimal)));

DataColumn col = new DataColumn();

colColumnName = "PreRevDate1";

colExpression = "ABS(ConvertToInt32(PreRevDate0))";

colDataType = typeof(decimal);

dtColumnsAdd(col);

DataRow dr = dtNewRow();

dr["PreRevDate0"] = -1;

dtRowsAdd(dr);

hadoop默认是读取文件的数据的单位是一行,怎么修改能使得hadoop以两行为单位进行读取数据

Hadoop中控制文件格式,split方式和record读取方式的类都继承自InputFormat这个抽象类。比如实现每次读取文本文件一行的就是TextInputFormat,这个类进一步使用LineRecordReader进行实际的读取 *** 作。以Hadoop 101为例,在LineRecordReader第97-99行:

newSize = inreadLine(value, maxLineLength,

Mathmax((int)Mathmin(IntegerMAX_VALUE, end-pos),

maxLineLength));

从文本行读取类LineReader in中读取一行写入record的value中。为了一次读取两行,可以将96-106行的while循环再复制粘贴一份在下面。

但是LineReader的readLine函数执行时会首先将value原来的值清空,但是我们读取第二行时不想将第一行的内容清空。因此对LineReader的readLine函数做一点修改:

为了保留原来的readLine函数,我们首先讲这个函数复制粘贴一份在下面,将readLine的函数声明做一点修改,增加是否clear value的判断:

public int readLine(Text str, int maxLineLength,

int maxBytesToConsume, boolean clear) throws IOException {

然后讲123行的strclear();修改为if (clear) {strclear();}

这样,在LineRecordReader的两个while循环中,第一次readLine应为:

newSize = inreadLine(value, maxLineLength,

Mathmax((int)Mathmin(IntegerMAX_VALUE, end-pos),

maxLineLength), true);

第二次readLine应为:

newSize = inreadLine(value, maxLineLength,

Mathmax((int)Mathmin(IntegerMAX_VALUE, end-pos),

maxLineLength), false);

搞定。

cpu是怎么读取内存数据

在计算机中CPU是通过数据总线与内存交换数据的CPU与内存交换数据是通过前端总线完成的,前端总线也是数据总线的一种。

这个flash是怎么读取的数据?

先看一下效果嘛

简单数据类型

User selectByPrimaryKey(Integer id);

sql映射:

<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="javalangInteger" >

select

<include refid="Base_Column_List" />

from basetb_user

where id = #{id,jdbcType=INTEGER}

</select>

对于简单数据类型,sql映射语句中直接#{变量名}这种方式引用就行了,其实这里的"变量名"可以是任意的。mapper接口方法传递过来的值,至于其叫什么名字其实是不可考也没必要知道的。

而且JAVA反射只能获取方法参数的类型,是无从得知方法参数的名字的。

比如上面这个示例中,使用#{id}来引用只是比较直观而已,使用其他名字来引用也是一样的。所以当在if元素中test传递的参数时,就必须要用_parameter来引用这个参数了。像这样:

<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="javalangInteger" >

select

<include refid="Base_Column_List" />

from tb_user

<if test="_parameter != 0">

where id = #{id,jdbcType=INTEGER}

</if>

</select>

可以用对应Mapper类,里面的方法名是对应的sql语句的ID名,这个可以去调用;还有一种,就是不用Mapper类,可以直接用xml的文件名id名获取的方式,这个方式要有像SqlSessionTemplate这样的类,提前定义好方法获取方式,然后调用就可以了

KeyWords: Mybatis 原理,源码,Mybatis Mapper 接口实现类,代理模式,动态代理,Java动态代理,ProxynewProxyInstance,Mapper 映射,Mapper 实现

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。我们在使用 Mybaits 进行 ,通常只需要定义几个 Mapper 接口,然后在编写一个 xml 文件,我们在配置文件中写好 sql , Mybatis 帮我们完成 Mapper 接口道具体实现的调用。以及将结果映射到 model bean 中。

我们在项目中所编写的众多的 Mapper 类只是一个接口(interface ),根据 Java 的多态性我们知道,可以使用接口接口作为形参,进而在运行时确定具体实现的对象是什么。但是,对于 Mapper 接口,我们并没有编写其实现类!Mybatis是如何找到其实现类,进而完成具体的 CRUD 方法调用的呢?原理何在?

为了弄清楚 Mapper 接口是如何找到实现类的,我们先回忆一下 Mybatis 是怎么使用的,根据实际的例子,进而一点点的去分析。这里的使用指的是Mybatis 单独使用,而不是整合 spring , 因为整合 spring 的话,还需要涉及 Mapper dao 装载到 spring 容器的问题,spring 帮忙创建数据源配置等问题。

通常我们使用 Mybatis 的主要步骤是:

从一段代码看起

上面我们概括了使用 Mybatis 的4个步骤。这4个步骤看起来很简单,但是用代码写出来就很多。我们不妨先记着这4个步骤,再去看代码,会容易点。

在这块代码中,第 1 部分我们使用了 Java 编码的形式来实现 SqlSessionFactory ,也可以使用 xml 。如果使用xml的话,上面的第一部分代码就是这样的:

我们本次的目标是弄清楚 “ Mapper 是如何找到实现类的 ”,我们注意上面代码 3 , 4 的位置:

这里 mapper 可以调用selectBlog(1) 这个方法,说明 mapper 是个对象,因为对象才具有方法行为实现啊。BlogMapper接口是不能实例化的,更没有具体方法实现。我们并没有定义一个类,让它实现BlogMapper接口,而在这里它只是通过调用sessiongetMapper() 所得到的。由此,我们可以推断:肯定是sessiongetMapper() 方法内部产生了BlogMapper的实现类。有什么技术可以根据BlogMapper 接口生成了一个实现类呢?想到这里,对于有动态代理 使用经验的程序员来说,很容易想到,这背后肯定是基于动态代理技术,具体怎么实现的呢?下面我们来根据源码一探究竟。

Mapper 接口的注册

从上面的代码中,我们知道 BlogMapper 接口的实现类是从sessiongetMapper中得来的,大概是基于动态代理技术实现。我们既然能够从SqlSession中得到BlogMapper接口的,那么我们肯定需要先在哪里把它放进去了,然后 SqlSession 才能生成我们想要的代理类啊。上面代码中有这么一行:

跟着这个 addMapper 方法的代码实现是这样的:

我们看到这里 mapper 实际上被添加到 mapperRegissry 中。继续跟进代码:

看到这里我们知道上面所执行的configurationaddMapper(BlogMapperclass); 其实最终被放到了HashMap中,其名为knownMappers ,knowMappers是MapperRegistry 类的一个私有属性,它是一个HashMap 。其Key 为当前Class对象,value 为一个MapperProxyFactory 实例。

这里我们总结一下: 诸如BlogMapper 之类的Mapper接口被添加到了MapperRegistry 中的一个HashMap中。并以 Mapper 接口的 Class 对象作为 Key , 以一个携带Mapper接口作为属性的MapperProxyFactory 实例作为value 。MapperProxyFacory从名字来看,好像是一个工厂,用来创建Mapper Proxy的工厂。我们继续往下看。

Mapper接口的动态代理类的生成

上面我们已经知道,Mapper 接口被到注册到了MapperRegistry中——放在其名为knowMappers 的HashMap属性中,我们在调用Mapper接口的方法的时候,是这样的:

这里,我们跟踪一下sessiongetMapper() 方法的代码实现,这里 SqlSession 是一个接口,他有两个实现类,一个是DefaultSqlSession,另外一个是SqlSessionManager,这里我们用的是DefaultSqlSession 为什么是DefaultSqlSession呢?因为我们在初始化SqlSessionFactory的时候所调用的SqlSessionFactoryBuilder的build()方法里边配置的就是DefaultSqlSession, 所以,我们进入到DefaultSession类中,看看它对sessiongetMapper(BlogMapperclass)是怎么实现的:

如代码所示,这里的 getMapper 调用了 configurationgetMapper , 这一步 *** 作其实最终是调用了MapperRegistry,而此前我们已经知道,MapperRegistry是存放了一个HashMap的,我们继续跟踪进去看看,那么这里的get,肯定是从这个hashMap中取数据。我们来看看代码:

我们调用的sessiongetMapper(BlogMapperclass);最终会到达上面这个方法,这个方法,根据BlogMapper的class对象,以它为key在knowMappers 中找到了对应的value —— MapperProxyFactory(BlogMapper) 对象,然后调用这个对象的newInstance()方法。根据这个名字,我们就能猜到这个方法是创建了一个对象,代码是这样的:

看到这里,就清楚了,最终是通过ProxynewProxyInstance产生了一个BlogMapper的代理对象。Mybatis 为了完成 Mapper 接口的实现,运用了代理模式。具体是使用了JDK动态代理,这个ProxynewProxyInstance方法生成代理类的三个要素是:

代理模式中,代理类(MapperProxy)中才真正的完成了方法调用的逻辑。我们贴出MapperProxy的代码,如下:

我们调用的 Blog blog = mapperselectBlog(1); 实际上最后是会调用这个MapperProxy的invoke方法。这段代码中,if 语句先判断,我们想要调用的方法是否来自Object类,这里的意思就是,如果我们调用toString()方法,那么是不需要做代理增强的,直接还调用原来的methodinvoke()就行了。只有调用selectBlog()之类的方法的时候,才执行增强的调用——即mapperMethodexecute(sqlSession, args);这一句代码逻辑。

而mapperMethodexecute(sqlSession, args);这句最终就会执行增删改查了,代码如下:

再往下一层,就是执行JDBC那一套了,获取链接,执行,得到ResultSet,解析ResultSet映射成JavaBean。

至此,我们已经摸清楚了Blog blog = mapperselectBlog(1); 中,BlogMapper接口调用到得到数据库数据过程中,Mybaitis 是如何为接口生成实现类的,以及在哪里出发了最终的CRUD调用。实际上,如果我们在调用Blog blog = mapperselectBlog(1);之前,把从slqSession中得到的 mapper 对象打印出来就会看到,输出大概是这样的:

动态代理没错吧,Java动态代理实在是太美妙了。

上面我们用层层深入的方式摸清楚了 Mapper接口是如何找到实现类的。我们分析了 Mapper接口是如何注册的,Mapper接口是如何产生动态代理对象的,Maper接口方法最终是如何执行的。总结起来主要就是这几个点:

以上就是关于Hadoop的Mapper是怎么从HDFS上读取TextInputFormat数据的全部的内容,包括:Hadoop的Mapper是怎么从HDFS上读取TextInputFormat数据的、mybatis中xml格式的mapper文件中接收入参时#和$的区别、请教Mybatis中如何在程序中获取Mapper中定义的SQL语句等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10076351.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存