2011-03-27 23:08 Sunday

RandomAccessFile

http://www.cnblogs.com/kelin1314/archive/2010/08/05/1793320.html

RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。

RandomAccessFile不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫不相干,甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。

基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream结合起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件。

只有RandomAccessFile才有seek搜寻方法,而这个方法也只适用于文件。BufferedInputStream有一个mark( )方法,你可以用它来设定标记(把结果保存在一个内部变量里),然后再调用reset( )返回这个位置,但是它的功能太弱了,而且也不怎么实用。

RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代了,你该考虑一下是不是用"内存映射文件"来代替RandomAccessFile了。

01import java.io.IOException;
02import java.io.RandomAccessFile;
03 
04public class TestRandomAccessFile {
05    public static void main(String[] args) throws IOException {
06        RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");
07        for (int i = 0; i < 10; i++) {
08            //写入基本类型double数据
09            rf.writeDouble(i * 1.414);
10        }
11        rf.close();
12        rf = new RandomAccessFile("rtest.dat", "rw");
13        //直接将文件指针移到第5个double数据后面
14        rf.seek(5 * 8);
15        //覆盖第6个double数据
16        rf.writeDouble(47.0001);
17        rf.close();
18        rf = new RandomAccessFile("rtest.dat", "r");
19        for (int i = 0; i < 10; i++) {
20            System.out.println("Value " + i + ": " + rf.readDouble());
21        }
22        rf.close();
23    }
24}

 

内存映射文件

内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。
fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。


MappedByteBuffer是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。

 


01import java.io.RandomAccessFile;
02import java.nio.MappedByteBuffer;
03import java.nio.channels.FileChannel;
04 
05public class LargeMappedFiles {
06    static int length = 0x8000000; // 128 Mb
07 
08    public static void main(String[] args) throws Exception {
09        // 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。
10        FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();
11        //注意,文件通道的可读可写要建立在文件流本身可读写的基础之上
12        MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);
13        //写128M的内容
14        for (int i = 0; i < length; i++) {
15            out.put((byte) 'x');
16        }
17        System.out.println("Finished writing");
18        //读取文件中间6个字节内容
19        for (int i = length / 2; i < length / 2 + 6; i++) {
20            System.out.print((char) out.get(i));
21        }
22        fc.close();
23    }
24}

 

 

尽管映射写似乎要用到FileOutputStream,但是映射文件中的所有输出 必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,可能写时要读的原因吧。

 

该程序创建了一个128Mb的文件,如果一次性读到内存可能导致内存溢出,但这里访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是调用操作系统的"文件映射机制"来提升性能的。

 

01/*
02 * 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
03 */
04package com.lwj.demo;
05 
06import java.io.*;
07 
08public class RandomAccessFileDemo {
09 public static void main(String[] args) throws Exception {
10  RandomAccessFile file = new RandomAccessFile("file", "rw");
11  // 以下向file文件中写数据
12  file.writeInt(20);// 占4个字节
13  file.writeDouble(8.236598);// 占8个字节
14  file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取
15  file.writeBoolean(true);// 占1个字节
16  file.writeShort(395);// 占2个字节
17  file.writeLong(2325451l);// 占8个字节
18  file.writeUTF("又是一个UTF字符串");
19  file.writeFloat(35.5f);// 占4个字节
20  file.writeChar('a');// 占2个字节
21 
22  file.seek(0);// 把文件指针位置设置到文件起始处
23 
24  // 以下从file文件中读数据,要注意文件指针的位置
25  System.out.println("——————从file文件指定位置读数据——————");
26  System.out.println(file.readInt());
27  System.out.println(file.readDouble());
28  System.out.println(file.readUTF());
29 
30  file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
31  System.out.println(file.readLong());
32 
33  file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。
34  System.out.println(file.readFloat());
35   
36  //以下演示文件复制操作
37  System.out.println("——————文件复制(从file到fileCopy)——————");
38  file.seek(0);
39  RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");
40  int len=(int)file.length();//取得文件长度(字节数)
41  byte[] b=new byte[len];
42  file.readFully(b);
43  fileCopy.write(b);
44  System.out.println("复制完成!");
45 }
46}
47 
48运行结果(同时生成相应的文件):
49 
50——————从file文件指定位置读数据——————
5120
528.236598
53这是一个UTF字符串
542325451
5535.5
56——————文件复制(从file到fileCopy)——————

 

2011-01-13 10:45 Thursday

如何使用android中的搜索功能(转载)

原文:http://lhc966.javaeye.com/blog/870001

 

这几天使用到了搜索,没仔细深入,步骤大概是这样的
1.Activity中调用onSearchRequested();
2.AndroidManifest.xml中添加
<meta-data android:name="android.app.searchable"  android:resource="@xml/searchable"/>   
@xml/searchable是自定义的,内容如下
<?xml version="1.0" encoding="utf-8"?>     
<searchable xmlns:android="http://schemas.android.com/apk/res/android"    
    android:label="@string/searchLabel" android:hint="@string/searchHint"  
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"  
    >     
</searchable>
3.点击@xml/searchable中的按钮的时候,android会搜索AndroidManifest.xml中的
<meta-data android:name="android.app.default_searchable" android:value=".SerachActivity" />   
4.SerachActivity是自定义的Activity,通过以下代码
Intent intent = getIntent();
String action = intent .getAction();
if (Intent.ACTION_SEARCH.equals(action )) {
	String queryString = intent.getStringExtra(SearchManager.QUERY);//queryString是查询的字符串
}
 流程是这样的,有错误请指出,谢谢

Tags: Android


2010-12-18 21:12 Saturday

android adb

通过 chcp命令改变代码页(为了解决中文乱码问题),UTF-8的代码页为65001
F:\>chcp 65001

显示 手机

adb devices

 通过远程shell命令来控制模拟器/设备实例.

adb shell

回到跟目录

cd /

打开应用程序文件夹

# cd /data/data/com.appspot.zqt
cd /data/data/com.appspot.zqt
# ls
ls
lib           shared_prefs
# cd shared_prefs
cd shared_prefs
# ls
ls
activity.CrazySMS.xml
# cat activity.CrazySMS.xml
cat activity.CrazySMS.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="firstStart" value="false" />
</map>

打开一个程序的数据库

# sqlite3 /data/data/com.jongla.android/databases/jongla.db
sqlite3 /data/data/com.jongla.android/databases/jongla.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>

 

1.数据库、表的建立,记录的添加、查询、修改和删除

F:\>sqlite3 database.db
sqlite> create table admin(username text,age integer);
sqlite> insert into admin values('kuang',25);
sqlite> select * from admin;
sqlite> update admin set username='kk',age=24 where username='kuang' and age=25;
sqlite> delete from admin where username='kk';

注:每条sql语句后必须以";"号结尾!

2.Sqlite系统命令

.bail ON|OFF
          Stop after hitting an error.  Default OFF
.databases             List names and files of attached databases(查看目前挂的数据库)
.dump ?TABLE? ...      Dump the database in an SQL text format(以SQL格式输出表结构)
.echo ON|OFF           Turn command echo on or off
.exit                  Exit this program(退出程序)
.explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.
.header(s) ON|OFF      Turn display of headers on or off
.help                  Show this message(显示帮助信息)
.import FILE TABLE     Import data from FILE into TABLE(把文件中的数据导入到表中,各字段用separator的值为分隔符)
.indices TABLE         Show names of all indices on TABLE
.load FILE ?ENTRY?     Load an extension library
.mode MODE ?TABLE?     Set output mode where MODE is one of:(输出格式)
                         csv      Comma-separated values(各字段以逗号为分隔符输出)
                         column   Left-aligned columns.  (See .width)(以.width设置的宽度显示各字段)
                         html     HTML <table> code(html表格格式输出)
                         insert   SQL insert statements for TABLE(以insert SQL语句形式输出)
                         line     One value per line(field = value的形式逐行输出)
                         list     Values delimited by .separator string(各字段以separator的值为分隔符输出)
                         tabs     Tab-separated values
                         tcl      TCL list elements
.nullvalue STRING      Print STRING in place of NULL values
.output FILENAME       Send output to FILENAME(设置把查询输出到文件,后面的输出结果都保存到文件中)
.output stdout         Send output to the screen(设置把查询结果输出到屏幕,默认)
.prompt MAIN CONTINUE  Replace the standard prompts(修改提示符)
.quit                  Exit this program(退出)
.read FILENAME         Execute SQL in FILENAME(执行文件中的SQL语句)
.schema ?TABLE?        Show the Create statements(以SQL格式输出表结构)
.separator STRING      Change separator used by output mode and .import(修改分隔符)
.show                  Show the current values for various settings(显示配置信息)
.tables ?PATTERN?      List names of tables matching a LIKE pattern(看看有创建了多少表)
.timeout MS            Try opening locked tables for MS milliseconds(超时时间,单位:毫秒)
.width NUM NUM ...     Set column widths for "column" mode(设置列宽)