1. 索引节点
UNIX系统中每个文件有一个唯一的索引节点,包含为进程存取文件所必须的信息。
inode以静态形式存在于磁盘上,内核把他们镀金内存索引节点表中以便操纵它们。包含内容:文件所有者、类型、时间、文件数据磁盘地址明细表,文件大小(偏移量表示)。
把索引节点的内容写入磁盘,和把文件内容写入磁盘不同,要注意区别。
内存中的索引节点与磁盘索引节点相比,还包含一些额外字段如状态(上锁等)、磁盘未知节点号、引用数等。当一个进程打开一个文件时,索引节点的引用数加一。知道其引用计数为0时,这个索引节点才能被放入空闲表,重新分配给另一个磁盘索引节点。与高速缓冲中的缓冲首部类似。
1)索引节点的存取
iget分配一个索引节点的内存拷贝,与高速缓冲的getblk几乎完全相同。内核把设备号和索引节点号映射到一个散列队列上,同时有一个空闲表,以进行搜索和分配。索引节点除锁控制外,还有一个计数器,一方面及时释放锁,另一方面防止节点被意外释放。
块号=((索引节点号 - 1)/每块的索引节点数目) + 索引节点表的起始块号
当内核知道设备和磁盘块号后,使用算法bread(会调用getblk得到缓冲区)读出该块,然后使用下面公式计算索引节点在该块中的字节偏移量:
((索引节点号 - 1) mod (每块索引节点数目)) * 磁盘索引节点大小
然后从磁盘索引节点把数据拷贝到内存索引节点上,并返回一个上锁状态的索引节点。
索引节点本身有一个高速缓存,与bread中的高速缓存不是同一个?
2. regular file structure
索引节点包含文件数据在磁盘上的未知明细表(用磁盘块序号表示)。为使索引节点保持较小的结构又能允许组织大文件,磁盘块地址存取分为三级索引:直接、一次间接、二次间接和三次间接。文件大小限制为4G(16G?)
进程存取文件中的数据时使用字节偏移量,内核把用户字节流转换成块:文件从第一个逻辑块开始,知道相应于该文件大小的逻辑块号。内核存取索引节点并把逻辑文件块转换成磁盘块。
文件偏移量转换成物理磁盘块算法为bmap。对于一个大的字节偏移量,特别是经过三次间接引用的,内核除存取索引节点与数据块之外,还要存取三个磁盘块,及时在高速缓冲中能找到这些磁盘块,但由于需要等候上了锁的缓冲区,操作代价仍会很高。
3. 目录
目录也是文件,只是它的数据是一系列目录表项,每个目录表项有一个索引节点号好一个包含在这个目录中的文件名组成。
4. 路径名到索引节点转换
namei每次分析路径名的一个分量,根据这个名字及正在搜索的目录,把这个分量转换成一个索引节点。每个进程在其工作目录中工作,所有路径名搜索都从进程的当前目录开始(或从指定的根目录)。
namei分析路径名时使用工作索引节点,
5. 为新文件分配索引节点
iget用来分配已知的索引节点,ialloc则用来把一个磁盘索引节点分配给一个新建立的文件。
文件系统包含一个索引节点线性表,如果类型字段为0,说明这个索引节点是空闲的。超级块包含一个数组,用于包文件系统中空闲的索引节点号缓存起来。(注意,是索引节点号,得到索引节点号后可用iget分配内存)。
当超级块中空闲索引节点表为空时,通过铭记索引节点来确定从磁盘上开始搜索空闲索引节点的位置,并把超级块中空闲表填满。铭记索引节点是最小的空闲索引节点号。
6. 磁盘块的分配
当进程往文件上写数据时,内核必须从文件系统中分配磁盘块,一用作数据块。超级块包含一个用来把文件系统中空闲磁盘块高速缓冲起来的数组。
mkfs把一个文件系统数据块组织到一个链表中,表中的每一个链是一个磁盘块。当内核想要从文件系统中分配一块时(算法alloc),它把超级块表中下一个可用块分配出去。如果该可用块是最后一个可用块,则读出该块内容(bread),把读出的所有块号拷贝到超级块中以填满空闲块备用。
前些时间学写了软件工程, 软件工程总结分了两个大的模块
面向过程
面向对象
的管理过程
之后紧接着就是UML 的学习,这个是对软件工程的进一步补充 ,是对设计中的一些类图,部署图等的设计。
再后来就是C#,设计模式的学习
这些都是对面向对象的进一步理解 ,发现他们之间或许应该有些联系,这个也是有人问起我的,虽然知道它们之间有联系,但是也没有什么总结的,只有别人问起来才去总结,真的有些慢的呀。
画了一个小小的图先简单描述下它们的关系啦
一、简介
语音识别现在应用越来越广泛了 比如语音写短信、语音搜索商品、语音搜索关键字等等,这遍我们就简单的谈谈国内比较流行的讯飞语音在android平台上的实现。
笔者认为:
google语音识别并不是十分符合中国人的习惯,且google语音识别一个重要弊端的是,需要用户手机上必须有google语音应用。
一般的国行android手机并没有,比如笔记手机小米就没有。需要下载单独google语音apk。所以用户体现自然不如讯飞。
但讯飞笔者认为,也有一定风险。讯飞应用协议中,他们是具有任何时候,停掉你语音识别服务的权限的,而且还不用和你商量。
一旦你的应用达到了百万级了,那么讯飞是要收取你一定的服务费的,所以一般大公司的项目基本上不会用讯飞语音或与讯飞语音合作比如小米,
Android4.0以上版本语音小助手就有小米与讯飞语音合作开发出来的。
二、讯飞Android小示例
先看看效果图:
嗯,看到效果图后下面就谈谈如何去实现效果:
2.1 到讯飞官网开发者专区中注册用户并获取appid 地址:http://open.voicecloud.cn/developer.php
2.2 新建android工程,并在清单文件中声明好相应的权限
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />2.3 下载libmsc.so与Msc.jar,并分别放在android工程的libs/armeabi与libs文件夹中,如图
3.4 使用示例如下,代码中都带有相应的注释了:
import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import com.iflytek.speech.RecognizerResult; import com.iflytek.speech.SpeechConfig.RATE; import com.iflytek.speech.SpeechError; import com.iflytek.ui.RecognizerDialog; import com.iflytek.ui.RecognizerDialogListener; /** * @author 陈淑飞 * 2013-1-8 上午1:10:24 */ public class HelloDemoActivity extends Activity implements OnClickListener { protected static final String TAG = "ThirdActivity"; private EditText txt_result; private RecognizerDialog rd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.demo); findView(); //RecognizerDialog(Context context, String params); "appid=1234567,usr=test,pwd=12345" usr、pwd不是必选的 //创建语音识别dailog对象,appid到讯飞就注册获取 rd = new RecognizerDialog(this ,"appid=50e1b967"); } private void findView() { txt_result = (EditText) findViewById(R.id.txt_result); findViewById(R.id.bt_search).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_search: showReconigizerDialog(); break; default: break; } } private void showReconigizerDialog() { //setEngine(String engine,String params,String grammar); /** * 识别引擎选择,目前支持以下五种 “sms”:普通文本转写 “poi”:地名搜索 “vsearch”:热词搜索 “vsearch”:热词搜索 “video”:视频音乐搜索 “asr”:命令词识别 params 引擎参数配置列表 附加参数列表,每项中间以逗号分隔,如在地图搜索时可指定搜索区域:“area=安徽省合肥市”,无附加参数传null */ rd.setEngine("sms", null, null); //设置采样频率,默认是16k,android手机一般只支持8k、16k.为了更好的识别,直接弄成16k即可。 rd.setSampleRate(RATE.rate16k); final StringBuilder sb = new StringBuilder(); Log.i(TAG, "识别准备开始............."); //设置识别后的回调结果 rd.setListener(new RecognizerDialogListener() { @Override public void onResults(ArrayList<RecognizerResult> result, boolean isLast) { for (RecognizerResult recognizerResult : result) { sb.append(recognizerResult.text); Log.i(TAG, "识别一条结果为::"+recognizerResult.text); } } @Override public void onEnd(SpeechError error) { Log.i(TAG, "识别完成............."); txt_result.setText(sb.toString()); } }); txt_result.setText(""); //先设置为空,等识别完成后设置内容 rd.show(); } }
笔者注:呵呵请大家转载时,注下来源呗,也帮我弄弄人气撒。
另:工程示例domo,已上传到csdn中(免积分哦),地址:http://download.csdn.net/detail/chenshufei2/4989030