Android大TXT文本文档读取

上次写了个 Android大TXT文本文档读取,但是提到不能往回读,这两天就顺手写了一下回翻的效果,当然回翻的时候鉴于手机CPU或者内存的缘故会觉得卡或者不卡,不过还好,自己测试的效果还行。倒是一直在后台如果有个读取的备份的话,此处是指InputStreamReader对象的备份,而不是读取Buffer的备份。

  以下这段代码已经放到开源项目Filexpert里了,在那个项目中,可以读取网络文件。大家如果感兴趣的话,也可以试试Filexpert,挺不错的一个项目,请大家多多支持。

  闲话少说,依旧上代码。

package net . wangliping . filemanager;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.CharBuffer;

import android.app.Activity;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ScrollView;

import com.swan.test.R;

public class TxtReader extends Activity implements
SwanTextView.OnPreDrawListener {

private static final String LOG_TAG = "TxtReader";
private static final int BUF_SIZE = 1024 * 2;
private static final int BUF_SHOW = 3;

private static final int ARROW_UP = 1;
private static final int ARROW_DOWN = 2;

private static String ENCODING = "GB2312";

private InputStreamReader mIsReader = null;
private Uri mUri = null;
private SwanTextView mTextShow;
private ScrollView mScrollView;
private String mStringShow = null;
private StringBuilder mStringBuilder = null;

private boolean mReadNext = true;
private boolean mReadBack = false;
private boolean mStopThread = false;

private int mPreBottom = -1;
private int mCurBottom = -1;
private int mReadBufNum = 0;
private int mBuffHeight = -1;
private int mPreScrollY = -1;

private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ARROW_DOWN:
mTextShow.setText((CharBuffer) msg.obj);
break;
case ARROW_UP:
mTextShow.setText((CharBuffer) msg.obj);
mScrollView.scrollTo(0, mBuffHeight);
break;
default:
super.handleMessage(msg);
}
}
};

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.txt_reader);

mUri = getIntent().getData();

mScrollView = (ScrollView) findViewById(R.id.text_show_scroll);

mTextShow = (SwanTextView) findViewById(R.id.text_show);
mTextShow.setOnPreDrawListener(this);

new TextShowTask().execute(mUri);
}

private void showText(Uri uri) throws IOException, InterruptedException {

mIsReader = new InputStreamReader(new FileInputStream(
uri.getPath()), ENCODING);

mStringBuilder = new StringBuilder();
int initBufSize = BUF_SIZE * (BUF_SHOW - 1);
char[] buf = new char[BUF_SIZE];

while (!mStopThread) {
int scrollY = mScrollView.getScrollY();
if (mCurBottom == scrollY && mPreScrollY < scrollY) {
mReadNext = true;
mReadBack = false;
} else if (mReadBufNum > BUF_SHOW && 0 == scrollY && mPreScrollY != scrollY) {
mReadNext = false;
mReadBack = true;
}

mPreScrollY = scrollY;

int len = -1;
if (mReadNext && (len = mIsReader.read(buf)) > 0) {
mReadNext = false;
mReadBufNum++;

if (mStringBuilder.length() > initBufSize) {
mStringBuilder.delete(0, BUF_SIZE);
mPreBottom = mCurBottom;

Message msg = mHandler.obtainMessage(ARROW_DOWN);
msg.obj = CharBuffer.wrap(mStringBuilder.toString());
mHandler.sendMessage(msg);

mStringShow = mStringBuilder.append(buf, 0, len).toString();
} else {
while (mStringBuilder.length() < initBufSize) {
mStringBuilder.append(buf);
mIsReader.read(buf);
mReadBufNum++;
}

mStringBuilder.append(buf);
Message msg = mHandler.obtainMessage(ARROW_DOWN);
msg.obj = CharBuffer.wrap(mStringBuilder.toString());
mHandler.sendMessage(msg);
}
} else if (mReadBack && mReadBufNum > BUF_SHOW) {
Log.d(LOG_TAG, "Prepare to read back");
mReadBack = false;
mIsReader.close();
new BackBufReadThread(mStringBuilder).start();
}
}
}

private class TextShowTask extends AsyncTask<Object, Object, Object> {
@Override
protected void onPostExecute(Object param) {
Log.d(LOG_TAG, "Send broadcast");
}

@Override
protected Object doInBackground(Object... params) {
Uri uri = (Uri) params[0];

try {
showText(uri);
} catch (Exception e) {
Log.d(LOG_TAG, "Exception", e);
}

return null;
}
}

private class BackBufReadThread extends Thread {
StringBuilder mSbPre = null;

public BackBufReadThread(StringBuilder sb) {
mSbPre = sb.delete(0, sb.length());
}

@Override
public void run() {
try {
mIsReader = new InputStreamReader(new FileInputStream(
mUri.getPath()), ENCODING);

char[] buf = new char[BUF_SIZE];
int i = 0;
while((mReadBufNum - BUF_SHOW) > ++i && mIsReader.read(buf) > 0) {
// Just to skip the inputstream. Any better methods?
}
mReadBufNum--;

for (i = 0; i < BUF_SHOW; i++) {
mIsReader.read(buf);
mSbPre.append(buf);
}


// mSbPre.delete(mSbPre.length() - BUF_SIZE, mSbPre.length()).insert(0, buf);
Message msg = mHandler.obtainMessage(ARROW_UP);
msg.obj = CharBuffer.wrap(mSbPre.toString());
mHandler.sendMessage(msg);
} catch (Exception e) {
Log.d(LOG_TAG, "Exception", e);
}
}
}

@Override
public void onPreDraw(int bottom) {
mCurBottom = bottom - mScrollView.getHeight();

if (!TextUtils.isEmpty(mStringShow)) {
// Use the last deleted buff to evaluate the height
mBuffHeight = mPreBottom - mScrollView.getScrollY();

// Set the text to add new content without flash the view
Message msg = mHandler.obtainMessage(ARROW_DOWN);
msg.obj = CharBuffer.wrap(mStringShow);
mHandler.sendMessage(msg);

mStringShow = null;
}
}

@Override
public void finish() {
mStopThread = true;
super.finish();
}
}

  资源文件和SwanTextView跟上次的文章一样,只不过为了名字命名好看点,把SwanTextView里的响应函数改成如下了:

@Override
protected void onDraw( Canvas canvas) {

if ( mPreBottom != getBottom()) {
mPreBottom = getBottom();

if (preDrawListener != null)
preDrawListener.onPreDraw(mPreBottom);
}

super.onDraw(canvas);
}

public static interface OnPreDrawListener {
public void onPreDraw(int bottom);
}

public void setOnPreDrawListener(OnPreDrawListener listener) {
preDrawListener = listener;
}

                                                                       原创文章,如需转载请注明【转烛空间】:http://wangliping.net

本文地址:http://wangliping.net/read-big-txt-2

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值