`
hecal
  • 浏览: 78887 次
社区版块
存档分类
最新评论

《转载》Android大TXT文本文档读取(续)

阅读更多

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

 

上次写了个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 ;
}

  代码不成熟,见笑了。

分享到:
评论

相关推荐

    彻底解决android读取中文txt的乱码(自动判断文档类型并转码

    在Android中,我们通常使用`BufferedReader`或`InputStreamReader`来读取TXT文件。为了防止乱码,我们可以尝试自动检测文件的编码类型,然后使用对应的编码打开文件。以下是一种可能的实现方式: 1. 使用第三方库:...

    android读取和保存GBK编码的TXT文档

    4. **读取内容**:现在你可以逐行读取TXT文档内容了。使用`BufferedReader`的`readLine()`方法,直到没有更多内容。 ```java String line; while ((line = br.readLine()) != null) { // 处理每一行内容 } ```...

    android txt文件保存读取操作

    2. **读取TXT文件**: - 对于内部存储的文件,可以使用`Context`的`openFileInput()`方法打开已存在的文件,然后用`BufferedReader`读取内容。 - 对于外部存储的文件,同样需要先构造文件路径,然后使用`...

    Android读取TXT文件

    本文将详细介绍如何在Android应用中读取TXT文件,并将其内容显示在TextView组件上。 首先,我们需要理解Android的文件系统结构。在Android设备中,应用通常有自己的私有存储空间,可以访问内部存储(Internal ...

    android:读取word文档

    在Android平台上,读取Word文档是一项常见的需求,特别是在开发企业级应用或文件处理类应用时。这个主题主要涉及如何在Android环境下使用各种库和API来实现Word文档的读取功能。下面将详细介绍这一过程。 首先,...

    Android读取并显示word文件的代码例子

    在Android平台上,开发人员...通过以上步骤,你可以在Android应用中实现读取和显示Word文档的功能,覆盖了从doc到docx的格式,并能正确处理图文混排的内容。实际开发中,可以根据需求进行调整,优化性能和用户体验。

    Android读取PPT、pptx文档

    这些文档通常用于展示和传达信息,而Android应用程序可能需要读取或显示这些内容。在这种情况下,Apache POI库是一个常用的解决方案,虽然它在Android上的应用可能面临一些挑战,比如界面渲染效果不佳。 Apache POI...

    Android TXT阅读器 源代码

    而TXT阅读器作为最基础的文本阅读应用之一,其源代码的学习对于Android开发者来说,是深入理解Android系统、UI设计以及文件处理等方面的重要途径。本文将围绕"Android TXT阅读器"的源代码进行详细解析,探讨其实现的...

    AndroidTXT 文本阅读器源码.zip

    2. 文本加载:读取TXT文件的核心在于文件I/O操作。Android提供了java.io.File和java.io.BufferedReader等类,用于读取文件内容。源码中可能采用了逐行读取的方式,将文本内容加载到内存中。 3. 文本渲染:在Android...

    Android 读取Doc 文件

    在Android平台上,由于原生系统并不支持直接读取Microsoft Office的DOC文件,因此开发者通常需要借助第三方库来实现这一功能。本主题的核心是利用Java的API和特定的库来处理DOC文档,以便在Android应用中展示或操作...

    安卓使用poi读取及修改word文档

    在Android平台上,通常我们会使用Java库来处理与Microsoft Office文档相关的任务,如读取和修改Word文档。Apache POI是一个广泛使用的开源库,它允许开发者用纯Java代码操作微软的Office格式,包括Word(.doc)、...

    android读取word文档

    在Android平台上,读取Word文档是一项常见...以上是关于Android平台读取.txt和Word文档的核心知识点,涵盖了文件访问、解析、查找和错误处理等多个方面。在实际开发中,应根据具体需求和项目规模进行适当的调整和优化。

    android调用系统内部打开word等文档

    在Android平台上,调用系统内置的应用程序来打开Word文档是一个常见的需求。这涉及到Android的Intent机制,通过Intent我们可以启动各种系统服务或者应用,包括查看、编辑文档等。下面将详细介绍如何实现这一功能。 ...

    android中poi生成word文档和excel文档

    总的来说,使用Apache POI在Android中生成Word和Excel文档涉及了多个步骤,包括数据读取、文件操作、文档结构构建以及格式化。这个过程需要对XML、Java I/O、Android文件系统权限管理和POI API有深入理解。开发者...

    Android应用源码之TXT文本阅读器源码-IT计算机-毕业设计.zip

    这篇文档将深入解析《Android应用源码之TXT文本阅读器源码》的开发细节,适合于正在学习Android应用开发的学生,尤其是那些准备进行毕业设计的同学。Android平台为开发者提供了丰富的API和工具,使得构建功能丰富的...

    android对.txt文件中的数据查询,查询成功并写一条记录到另一个文档中

    在Android平台上,对`.txt`文件进行数据查询和记录写入是常见的操作,尤其是在处理文本日志、配置文件或者简单的数据存储时。本教程将详细讲解如何实现这一功能,涉及的主要知识点包括Android的文件系统操作、文件...

    Android解析并显示doc,docx,xls,xlsx文件

    `doc`是早期版本的Microsoft Word文档,而`docx`是基于XML的较新格式,包含文本、样式、图像等元素。`xls`是老版Excel表格文件,而`xlsx`同样是XML为基础的新格式,用于存储表格数据和格式。 要解析这些文件,我们...

    AndroidTXT-文本阅读器源码.zip

    4. **文件操作**:读取TXT文件需要使用Android的文件I/O系统。`java.io.File`类用于处理文件路径,`BufferedReader`或`InputStreamReader`用于读取文本内容。同时,需要考虑文件权限管理,特别是针对外部存储的读写...

    AndroidTXT 文本阅读器源码-IT计算机-毕业设计.zip

    2.3 文件读取:通过Java的FileInputStream或BufferedReader类读取TXT文件内容,将文本加载到界面上。 2.4 文本渲染:Android提供了TextView控件,用于显示文本。源码可能自定义了TextView子类,以实现特定的阅读...

    安卓使用poi XWPFDocument读取及修改word文档

    在本场景中,我们将重点讨论如何在Android应用中使用Apache POI的XWPFDocument类来读取和修改Word(.docx)文档。 1. **Apache POI介绍** Apache POI是一个开源项目,主要目的是使Java开发者能够读写Microsoft ...

Global site tag (gtag.js) - Google Analytics