android 大文本读取

向虚拟机sk卡复制文件  adb push aaa.txt /sdcard/book.txt

BigTextReader代码:

package dingq.BigTxtReader;
// Android大TXT文本文档读取
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;

public class BigTxtReader extends Activity implements
        SwanTextView.OnPreDrawListener {

    private static final String LOG_TAG = "BigTxtReader";
    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.main);

        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];
            uri = Uri.parse("/sdcard/books/aaa.txt");

            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);
            }
        }
    }

    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

package dingq.BigTxtReader;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextView;

public class SwanTextView extends TextView {

    private int mPreBottom = -1;
    private OnPreDrawListener preDrawListener = null;
    
    public SwanTextView(Context context) {
        super(context);
    }

    public SwanTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwanTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }
    
@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;
}
}


布局main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text_show_linear" android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ScrollView android:id="@+id/text_show_scroll"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <dingq.BigTxtReader.SwanTextView
            android:id="@+id/text_show" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:scrollbars="none">
        </dingq.BigTxtReader.SwanTextView>
    </ScrollView>
</LinearLayout>


Mainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="dingq.BigTxtReader"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".BigTxtReader"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>


</manifest> 




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值