当前位置: 首页 > 工具软件 > FBReader > 使用案例 >

FBReader支持txt插件

许俊贤
2023-12-01
package org.geometerplus.fbreader.formats.txt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.geometerplus.fbreader.bookmodel.BookModel;
import org.geometerplus.fbreader.bookmodel.BookReader;
import org.geometerplus.fbreader.formats.JavaFormatPlugin;
import org.geometerplus.fbreader.library.ReadBook;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.filesystem.ZLTxtPhysicalFile;
import org.geometerplus.zlibrary.core.image.ZLImage;
import org.geometerplus.zlibrary.core.util.ZLArrayUtils;

import com.chineseall.reader.ui.view.FileLocalCache;
import com.chineseall.readerapi.exception.ErrorMsgException;
import com.chineseall.readerapi.util.LogUtil;

public class TxtPlugin extends JavaFormatPlugin {

	private static final int BUFF_SIZE = 512 * 1024;
	private static byte[] readBuffer = new byte[BUFF_SIZE];
	BookReader txtReader;
	public TxtPlugin() {
		super(ZLTxtPhysicalFile.ExtensionName);
		
	}

	@Override
	public String readAnnotation(ZLFile file) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ZLImage readCover(ZLFile file) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean readMetaInfo(ReadBook book) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean readModel(BookModel model) {
//		LogUtil.startTime("readmodel");
		txtReader = new BookReader(model);
		txtReader.setMainTextModel();
//		LogUtil.endTime("readmodel");
		
		LogUtil.startTime("read");
		readContent(model.Book.File.getPath());
		LogUtil.endTime("read");
		return true;
	}
	
	private byte[] myUnderflowByteBuffer = new byte[4];
	private int myUnderflowLength;
	private int myTextBufferLength;
	private char[] myTextBuffer = new char[512 * 1024];
	CharsetDecoder myByteDecoder = null;

	
	public final void addByteData(byte[] data, int start, int length) {
		final int oldLength = myTextBufferLength;
		
//		LogUtil.startTime("addbyte");
		
		if (myTextBuffer.length < oldLength + length) {
			myTextBuffer = ZLArrayUtils.createCopy(myTextBuffer, oldLength, oldLength + length);
		}
		final CharBuffer cb = CharBuffer.wrap(myTextBuffer, myTextBufferLength, length);

		if (myUnderflowLength > 0) {
			int l = myUnderflowLength;
			while (length-- > 0 && l < 4) {
				myUnderflowByteBuffer[l++] = data[start++];
				final ByteBuffer ubb = ByteBuffer.wrap(myUnderflowByteBuffer);
				myByteDecoder.decode(ubb, cb, false);
				if (cb.position() != oldLength) {
					myUnderflowLength = 0;
					break;
				}
			}
			if (length == 0) {
				myUnderflowLength = l;
				return;
			}
		}
//        LogUtil.endTime("addbyte");
//        
//        LogUtil.startTime("addcontent");
		ByteBuffer bb = ByteBuffer.wrap(data, start, length);
		myByteDecoder.decode(bb, cb, false);
		myTextBufferLength = cb.position();
		int rem = bb.remaining();
		if (rem > 0) {
			for (int i = 0, j = start + length - rem; i < rem;) {
				myUnderflowByteBuffer[i++] = data[j++];
			}
			myUnderflowLength = rem;
		}
//        LogUtil.startTime("=====addcontentData=");
		addContentsData(myTextBuffer, oldLength, myTextBufferLength - oldLength);
//		LogUtil.endTime("=====addcontentData=");
//		LogUtil.endTime("addcontent");
	}
	
	/**
	 * 获取byte[]对应的格式化的段落字符数组
	 * 一个段落为一个一维的字符数组
	 * @param data
	 * @param start
	 * @param length
	 * @param isFrontToLastDataBlock 该数据块是不是位于上次操作数据块前面
	 * @return
	 */
	public final char[][] getFormatsParaphData(byte[] data, int start, int length, boolean isFrontToLastDataBlock) {
		if(isFrontToLastDataBlock)
		{
			myUnderflowLength = 0;
		}
		final int oldLength = myTextBufferLength;
		if (myTextBuffer.length < oldLength + length) {
			myTextBuffer = ZLArrayUtils.createCopy(myTextBuffer, oldLength, oldLength + length);
		}
		final CharBuffer cb = CharBuffer.wrap(myTextBuffer, myTextBufferLength, length);

		if (myUnderflowLength > 0) {
			int l = myUnderflowLength;
			while (length-- > 0 && l < 4) {
				myUnderflowByteBuffer[l++] = data[start++];
				final ByteBuffer ubb = ByteBuffer.wrap(myUnderflowByteBuffer);
				myByteDecoder.decode(ubb, cb, false);
				if (cb.position() != oldLength) {
					myUnderflowLength = 0;
					break;
				}
			}
			if (length == 0) {
				myUnderflowLength = l;
				return null;
			}
		}

		ByteBuffer bb = ByteBuffer.wrap(data, start, length);
		myByteDecoder.decode(bb, cb, false);
		myTextBufferLength = cb.position();
		int rem = bb.remaining();
		if (rem > 0) {
			for (int i = 0, j = start + length - rem; i < rem;) {
				myUnderflowByteBuffer[i++] = data[j++];
			}
			myUnderflowLength = rem;
		}
		return getContentsData(myTextBuffer, oldLength, myTextBufferLength - oldLength);
	}
	
	/**
	 * 
	 */
	private StringBuilder cacheBuffer = new StringBuilder(1024 * 256);
	private StringBuilder headerBuffer = new StringBuilder();
	private StringBuilder endBuffer =  new StringBuilder();
	
	private char[][] getContentsData(char[] charBuffer, int offset, int length)
	{
		//cacheBuffer此时内容若不为空,则为上次读取时,末尾未结尾的段落内容.
		if(charBuffer != null)
		{
			cacheBuffer.insert(0, headerBuffer);
			headerBuffer.delete(0, headerBuffer.length());
			cacheBuffer.append(headerBuffer, offset, length);
			cacheBuffer.insert(cacheBuffer.length(), endBuffer);
			endBuffer.delete(0, endBuffer.length());
		}
		charBuffer = null;
		
		String formatContents =formatParagraph(cacheBuffer.toString());
		String[] chapterContents = formatContents.split("\r\n");
		formatContents = null;
		char[][] contentData = null;
		
		if(chapterContents.length > 2)
		{
			headerBuffer.append(chapterContents[0]);
			contentData = new char[chapterContents.length - 2][];
			for(int i = 1; i < chapterContents.length - 1; i++)
			{
				contentData[i - 1] = chapterContents[i].toCharArray();
				chapterContents[i] = null;
			}
			endBuffer.append(chapterContents[chapterContents.length - 1]);
		}
		else
		{
			headerBuffer.append(chapterContents[0]);
			endBuffer.append(chapterContents[0]);
		}
		chapterContents[chapterContents.length - 1] = null;
		myTextBufferLength = 0;
		chapterContents = null;
		
		return contentData;
	}
	
	private void addContentsData(char[] charBuffer, int offset, int length)
	{
		LogUtil.startTime("=if");
		
		LogUtil.startTime("1111");
		if(charBuffer != null)
		{
			cacheBuffer.append(charBuffer, offset, length);
		}
		charBuffer = null;
		LogUtil.endTime("1111");
		
		LogUtil.startTime("2222");
		LogUtil.startTimeMillis("format");
		String formatContents =formatParagraph(cacheBuffer.toString());
		LogUtil.endTimeMillis("format");
		
		LogUtil.startTimeMillis("chapterContents");
		String[] chapterContents = formatContents.split("\r\n");
		LogUtil.endTimeMillis("chapterContents");
		formatContents = null;
		LogUtil.endTime("2222");
		
		LogUtil.endTime("=if");
		
		LogUtil.startTime("=for");
		for(int i = 0; i < chapterContents.length - 1; i++)
		{
			txtReader.beginParagraph();
			txtReader.addData(chapterContents[i].toCharArray());
			txtReader.endParagraph();
			chapterContents[i] = null;
		}
		LogUtil.endTime("=for");
		
		LogUtil.startTime("null");
		cacheBuffer.delete(0, cacheBuffer.length());
		cacheBuffer.append(chapterContents[chapterContents.length - 1]);
		chapterContents[chapterContents.length - 1] = null;
		myTextBufferLength = 0;
		chapterContents = null;
		System.gc();
		LogUtil.endTime("null");
	}
	
	/***
	 * @param fullPath
	 */
	//1.
	private void readContent(String fullPath)  
	{
		
		File file = new File(fullPath);
		FileInputStream input = null;
		try {
			
			
			input = new FileInputStream(file);
			int numRead = 0;
			//FileChannel fc = input.getChannel();
			
			String encoding = FileLocalCache.getTextCode(fullPath);  //获取编码
			String textCode = FileLocalCache.coverEncoding(encoding);
			myByteDecoder = createDecoder(textCode);
			
			//MappedByteBuffer mapBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
//			LogUtil.startTime("while");
			while ((numRead = input.read(readBuffer, 0, readBuffer.length)) > 0) {
				//numRead = mapBuffer.remaining() >BUFF_SIZE ? BUFF_SIZE: mapBuffer.remaining();
				//mapBuffer.get(readBuffer, 0, numRead);
				addByteData(readBuffer, 0, numRead);
				
			}
//			LogUtil.endTime("while");
			//fc.close();
			
			txtReader.beginParagraph();
			txtReader.addData(cacheBuffer.toString().toCharArray());
			txtReader.endParagraph();
			cacheBuffer = null;
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			try {
				input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.gc();
		System.gc();
		
	}
	
	public static String formatParagraph(String srcContent) {
		if(srcContent.contains("\t")){
			srcContent = srcContent.replaceAll("\t", "");
		}
		Pattern pattern1 = Pattern.compile("\n[  ]*\n");//Chinese space and English space
		Matcher matcher1 = pattern1.matcher(srcContent);
		String srcContent2 = matcher1.replaceAll("\n");
		
		Pattern pattern2 = Pattern.compile("\n[  ]*");//Chinese space and English space
		Matcher matcher2 = pattern2.matcher(srcContent2);
		
		pattern1 = null;
		matcher1 = null;
		srcContent2 = null;
		return (" "+matcher2.replaceAll("\r\n "));
	}
	
	
	protected final CharsetDecoder createDecoder(String encoding) throws UnsupportedEncodingException {
		return Charset.forName(encoding).newDecoder().onMalformedInput(CodingErrorAction.REPLACE)
				.onUnmappableCharacter(CodingErrorAction.REPLACE);
	}
	private HashMap<String, char[][]> readContentCaches = new HashMap<String, char[][]>();
	private void loadNextBlock()
	{
		
	}
	private void loadPreviousBlock()
	{
		
	}
	FileInputStream fos = null;
	FileChannel fc = null;
	private int curReadPos = 0;
	private  MappedByteBuffer mapBuffer = null;
	private int getFixedReadMaxNum()
	{
		return mapBuffer.remaining() > BUFF_SIZE ? BUFF_SIZE : mapBuffer.remaining();
	}
	
	private void loadBlockContent()
	{
		mapBuffer.position(curReadPos);
		
		mapBuffer.get(readBuffer, 0, getFixedReadMaxNum());
		addByteData(readBuffer, 0, getFixedReadMaxNum());
		
	}
	
	private void initWork(String bookPath) throws ErrorMsgException
	{
		File bookFile = new File(bookPath);
		try {
			fos = new FileInputStream(bookFile);
			fc = fos.getChannel();
			mapBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, bookFile.length());
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
			throw new ErrorMsgException("文件已丢失!");
		} catch (IOException e) {
			e.printStackTrace();
			throw new ErrorMsgException("打开文件失败!");
		}
	}
	private void destroyWork()
	{
		if(fc != null)
		{
			try {
				fc.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		fc = null;
		if(fos != null)
		{
			try {
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		fos = null;
		mapBuffer = null;
	}
}

package com.chineseall.reader.ui.view;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.UnsupportedCharsetException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.mozilla.universalchardet.UniversalDetector;

import android.graphics.Paint;
import android.graphics.Rect;

/**
  *  文件读写工具
  *
  * @author:WUYU
  * @since :Jdk1.6
  * @version: 1.0
  * @date: 2011-7-21
  * 开发公司:中文在线互联网事业部
  * 版权:本文件版权归属中文在线互联网事业部
 */
public class FileLocalCache {

    private static final String cacheDir = "CHINESEALL_CACHE";

    /**
     * 检测sdcard上的cache目录,没有则创建
     * 
     * @return
     */
    public static boolean checkDir() {
        File f = new File(cacheDir);
        if (!f.exists()) {
            return f.mkdirs();
        }
        return true;
    }

    /**
     * 根据url从sdcard取得缓存文件读取输入流
     * 
     * @param url
     *            生成文件名的URL
     * @return 文件输入流FileInputStream
     */
    public static InputStream load(String url) {
        if (checkDir()) {

            String md5 = md5(url);
            File f = new File(cacheDir + md5);
            if (f.exists()) {
                try {
                    return new FileInputStream(f);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 将输入流保存到sdcard文件,并返回该文件的FileInputStream
     * 
     * @param url
     *            生成文件名的URL
     * @param in
     *            输入流
     * @return 保存文件的FileInputStream
     */
    public static InputStream save(String url, InputStream in) {
        if (checkDir()) {
            String md5 = md5(url);
            try {
                File f = new File(cacheDir + md5);
                if (!f.exists()) {
                    f.createNewFile();
                }
                FileOutputStream out = new FileOutputStream(f);

                int b;
                do {
                    b = in.read();
                    if (b != -1) {
                        out.write(b);
                    }
                } while (b != -1);
                in.close();
                out.flush();
                out.close();
                return new FileInputStream(f);

            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } else {
            return in;
        }

    }

    /**
     * 将url转换成md5对应的字符串
     * 
     * @param url
     * @return
     */
    public static String md5(String url) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(url.getBytes("UTF-8"));
            byte messageDigest[] = md5.digest();

            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < messageDigest.length; i++) {
                String t = Integer.toHexString(0xFF & messageDigest[i]);
                if (t.length() == 1) {
                    hexString.append("0" + t);
                } else {
                    hexString.append(t);
                }
            }
            return hexString.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 清空sdcard下的文件
     */
    public static void clearCache() {
        File f = new File(cacheDir);
        if (f.exists() && f.isDirectory()) {
            File flist[] = f.listFiles();
            for (int i = 0; flist != null && i < flist.length; i++) {
                flist[i].delete();
            }
        }
    }

    /**
     * 得到缓存文件sdcard的大小
     * 
     * @return
     */
    public static String getCacheSize() {
        long size = 0;
        File f = new File(cacheDir);
        if (f.exists() && f.isDirectory()) {
            File flist[] = f.listFiles();
            for (int i = 0; flist != null && i < flist.length; i++) {
                size = size + flist[i].length();
            }

        }
        if (size < 1000) {
            return "0k";
        } else if (size < 1000000) {
            return size / 1000 + "k";
        } else {
            return size / 1000000 + "m";
        }
    }

    /**
     * 根据URL从sdcard缓存文件读取数据
     * 
     * @param url
     *            指定文件名称的URL
     * @return 文件内容字符串
     */
    public static String load2(String url) {
        String md5 = md5(url);
        File f = new File(cacheDir + md5);
        // Cache in an hour
        long expiredTime = 3600000l;
        // 没有超时时间
        expiredTime = Long.MAX_VALUE;

        if (f.exists() && System.currentTimeMillis() - f.lastModified() < expiredTime) {

            FileInputStream fstream = null;

            try {
                fstream = new FileInputStream(f);
                long length = f.length();

                byte[] bytes = new byte[(int) length];

                // Read in the bytes
                int offset = 0;
                int numRead = 0;
                while (offset < bytes.length && (numRead = fstream.read(bytes, offset, bytes.length - offset)) >= 0) {
                    offset += numRead;
                }

                return new String(bytes, "UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fstream != null) {
                    try {
                        fstream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return null;
    }

    /**
     * 将URL抓取的内容保存到sdcard缓存文件
     * 
     * @param url
     *            url
     * @param c
     *            url对应的文件内容字符串
     * @param append
     *            true,表示追加到文件中
     */
    public static void store(String url, String c, boolean append) {
        if (!checkDir())
            return;

        String md5 = md5(url);
        File f = new File(cacheDir + md5);

        try {
            FileOutputStream out;
            out = new FileOutputStream(f, append);
            out.write(c.getBytes("UTF-8"));
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将日志按行写入文件
     * 
     * @param url
     *            日志文件名url
     * @param content
     *            写入内容
     * @param isAppend
     *            是追加还是替换
     */
    public static void storeLine(String url, String content, boolean isAppend) {
        if (!checkDir())
            return;

        String md5 = md5(url);
        File f = new File(cacheDir + md5);
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter(f, isAppend));
            writer.write(content + "\n");
            writer.flush();
            writer.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据URL从缓存文件按行读取数据,并返回字符串数组
     * 
     * @param url
     *            指定文件名称的URL
     * @return 文件内容字符串数组,每行为一个字符串
     */
    public static List<String> loadLine(String url) {
        List<String> tmpList = new ArrayList<String>();

        String md5 = md5(url);
        File f = new File(cacheDir + md5);
        if (!f.exists())
            return tmpList;

        FileReader fr = null;
        BufferedReader bf = null;
        try {
            fr = new FileReader(f);
            bf = new BufferedReader(fr);
            String line = bf.readLine();
            while (line != null) {
                line = line.trim();
                if (!line.equals("")) {
                    tmpList.add(line);
                }
                line = bf.readLine();
            }
            bf.close();
            fr.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tmpList;

    }

    /**
     * 删除sdcard下的文件指定文件
     * 
     * @param url
     *            指定文件名称的URL
     * 
     */
    public static void clearFile(String url) {
        String md5 = md5(url);
        File f = new File(cacheDir + md5);
        if (f != null && f.exists())
            f.delete();
    }

    /**
     * --从网络抓取文件,并保存到sdcard,可以抓取文本、图片、mp3、flash等,
     * 
     * 
     * @param url
     *            要抓取的url地址
     * @param isCover
     *            true 表示直接覆盖;false 表示如果已经存在,则不抓取
     * 
     */
    public static void store(String url, boolean isCover) {
        HttpURLConnection conn = null;
        URL l_url = null;
        try {
            String fileName = cacheDir + md5(url);
            if (!isCover) {
                File f = new File(fileName);
                if (f != null && f.exists()) {
                    return;
                }
            }
            l_url = new URL(url);
            conn = (HttpURLConnection) l_url.openConnection();
            conn.connect();
            InputStream inputstream = conn.getInputStream();

            FileOutputStream file = new FileOutputStream(fileName);
            BufferedInputStream bi = new BufferedInputStream(inputstream);
            while (bi.available() > 0) {
                file.write(bi.read());
            }
            file.flush();
            file.close();
            bi.close();
            inputstream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * --从网络抓取文件,并保存到sdcard,可以抓取文本、图片、mp3、flash等,
     * 
     * 
     * @param url
     *            要抓取的url地址
     * 
     * @param imageName
     *            文件名词
     * 
     * @param isCover
     *            true 表示直接覆盖;false 表示如果已经存在,则不抓取
     * 
     */
    public static void storeImage(String url, String imageName, boolean isCover) {
        HttpURLConnection conn = null;
        URL l_url = null;
        try {
            String fileName = cacheDir + imageName;
            if (!isCover) {
                File f = new File(fileName);
                if (f != null && f.exists()) {
                    return;
                }
            }
            l_url = new URL(url);
            conn = (HttpURLConnection) l_url.openConnection();
            conn.connect();
            InputStream inputstream = conn.getInputStream();

            FileOutputStream file = new FileOutputStream(fileName);
            BufferedInputStream bi = new BufferedInputStream(inputstream);
            while (bi.available() > 0) {
                file.write(bi.read());
            }
            file.flush();
            file.close();
            bi.close();
            inputstream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据URL从缓存文件读取数据,返回文件内容字符串
     * 
     * @param url
     *            指定文件名称的URL
     * @return 文件内容字符串
     */
    public static String loadText(String url) {
        String result = "";

        String md5 = md5(url);
        File f = new File(cacheDir + md5);
        if (!f.exists())
            return result;
        StringBuffer sb = new StringBuffer();
        FileReader fr = null;
        BufferedReader bf = null;
        try {
            fr = new FileReader(f);
            bf = new BufferedReader(fr);
            String line = bf.readLine();
            while (line != null) {
                line = line.trim();
                if (!line.equals("")) {
                    sb.append(line);
                }
                line = bf.readLine();
            }
            result = sb.toString();

            bf.close();
            fr.close();
            sb = null;

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    
//    /**
//	 * 判断字符集编码
//	 */
//	public static String GetTextCode(String fileName){
//		String Text_CODE = "";
//		try{
//			FileInputStream fileIS = new FileInputStream(fileName);
//			BufferedInputStream buf = new BufferedInputStream(fileIS);
//			buf.mark(4);
//			byte[] first3bytes = new byte[3];
//			buf.read(first3bytes);
//			buf.reset();
//			if(first3bytes[0] == (byte)0xEF && first3bytes[1] == (byte)0xBB && first3bytes[2] == (byte)0xBF) {
//				Text_CODE = "utf-8";
//			}else if(first3bytes[0] == (byte)0xFF && first3bytes[1] == (byte)0xFE) {
//				Text_CODE = "unicode";
//			}else if(first3bytes[0] == (byte)0xFE && first3bytes[1] == (byte)0xFF) {
//				Text_CODE = "utf-16be";
//			}else if(first3bytes[0] == (byte)0xFF && first3bytes[1] == (byte)0xFF) {
//				Text_CODE = "utf-16le";
//			}else {
//				Text_CODE = "GBK";
//			}
//		}
//		catch(FileNotFoundException e) {
//			e.printStackTrace();
//		}catch(IOException e) {
//			e.printStackTrace();
//		}
//		return Text_CODE;
//	}
	
    /**
     * 判断文件编码方式
     */
	public static String getTextCode(String filePath){
		String encoding = "";
		byte[] buf = new byte[4096];
		
		FileInputStream fInputStream;
        try {
	        fInputStream = new FileInputStream(filePath);
			UniversalDetector detector = new UniversalDetector(null);
		    int nread;
		    while ((nread = fInputStream.read(buf)) > 0 && !detector.isDone()) {
		      detector.handleData(buf, 0, nread);
		    }
		    detector.dataEnd();
		    encoding = detector.getDetectedCharset();
		    detector.reset();
        } catch (FileNotFoundException e) {
	        e.printStackTrace();
        } catch(IOException e){
        	e.printStackTrace();
        }
	    
	    return encoding;
	}
	
	/**
	 * 为了支持java读取文件做简单的编码处理
	 * 
	 * ISO-2022-CN
	 * BIG5
	 * EUC-TW
	 * GB18030
	 * HZ-GB-23121 
	 * 
	 * @param encoding 
	 * 		文本的编码格式
	 * @return
	 * 		
	 */
	public static String coverEncoding(String encoding){
		String str = "";
		
		if(encoding == null){
			return "gbk";
		}
		if(encoding.equals("GB18030") || encoding.equals(" ISO-2022-CN") || encoding.equals("BIG5")
				|| encoding.equals("EUC-TW") || encoding.equals("HZ-GB-23121")){
			str = "GBK";
		}else{
			str = encoding;
		}
		return str;
	}
	
	/**
	 *  返回fileName文件的Bytes数
	 *  
	 * @param fileName
	 * @return 
	 */
	public static int getFileBytes(String fileName){
		try {
	        FileInputStream fInputStream = new FileInputStream(fileName);
	        return fInputStream.available();
        } catch (FileNotFoundException e) {
	        e.printStackTrace();
	        return 0;
        } catch (IOException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        }
        return 0;
	}
	
	/**
	 * 返回file文件包含的页数
	 * 
	 * @param skipBytes
	 * @param fileName
	 * @param textCode
	 * @param pageLineNum
	 * @param screenWidth
	 * @param fontHeight
	 * @param lineOffset
	 * @param textPaint
	 * @return 0:存在异常
	 */
	public static int getFilePageNum(long skipBytes,String fileName
			,String textCode,int pageLineNum,int screenWidth,int 
				fontHeight ,float lineOffset,Paint textPaint) {
		
		char ch;
		int strWidth = 0;
		int real_line = 0;
		int i=0;
		int pageNum = 0;
		int curByte = 0;
//		final Paint pFont = new Paint();
		
		try {
			FileInputStream fInputStream = new FileInputStream(fileName);
			curByte = fInputStream.available();
			InputStreamReader inputStreamReader = new InputStreamReader(fInputStream, textCode);
			BufferedReader in = new BufferedReader(inputStreamReader);
			
			System.out.println("===========================华丽的分割线===================================");
			char buff[] = new char[curByte];
			in.read(buff, 0, curByte);
			for(i=0; i < curByte; i++) {
				float[] widths = new float[1];
//				TextView textView = new TextView();
				ch = buff[i];
				String str = String.valueOf(ch);
				int wid = textPaint.getTextWidths(str, widths);
				
//				Paint paint = new Paint();
				float strW = textPaint.measureText(str);
				
//				paint.setTextSize(tv.getTextSize());
				
				Rect rect = new Rect();
				textPaint.getTextBounds(str, 0, 1, rect);
				
//				AndroidUtils.Logd("getStringFromFileForward skipBytes = "+skipBytes+"fileName = "+fileName
//						+textCode+" curByteInPage = "+curByteInPage+" pageLineNum = "+pageLineNum+
//							" screenWidth = "+screenWidth+" fontHeight = "+fontHeight + " lineOffset = "+lineOffset
//								+" widths.length = "+widths.length);
				
//				if (ch == '\n'){
//					real_line++;
//					strWidth = 0;
//				}else{
//					strWidth += (int) (Math.ceil(widths[0]));
//					if (strWidth > screenWidth){
//						real_line++;
//						i--;
//						strWidth = 0;
//					}else{
//						if (i == (curByte -1)){
//							real_line++;
//						}
//					}
//				}

				//--------------------------Test
				pageNum++;
//				System.out.println(" getFilePageNum srt = ["+str
//						+"] (int) (Math.ceil(widths[0])) = "+(int) (Math.ceil(widths[0]))+
//							" wid = "+wid);
				int W = (int) (Math.ceil(widths[0]));
					if(pageNum == 200){
						break;
					}
				
			}
			in.close();
	    	return pageNum;
		}catch (UnsupportedCharsetException e) {
			// TODO: handle exception
		}catch (Exception e) {
			System.out.println("Java Error!!!!!!!!!!");
			e.printStackTrace();
		}
		return 0;
	}
	
	/**
	 * Test 测试
	 * @return
	 */
	public static StringBuffer getTestFile(String fileName,String textCode){
		
		int curByte;
		char ch;
		
		//换行标示
		int indexN = 0;
		//文字标示
		int indexText = 0;
		
		try {
			FileInputStream fInputStream = new FileInputStream(fileName);
			curByte = fInputStream.available();
//			curByte = 10*10*1000;
			InputStreamReader inputStreamReader = new InputStreamReader(fInputStream, textCode);
			BufferedReader in = new BufferedReader(inputStreamReader);
			
			StringBuffer sb = new StringBuffer();
			char[] buff = new char[curByte];
			in.read(buff, 0, curByte);
			for(int i=0; i < curByte; i++) {
					ch = buff[i];
					
					if (ch == '\n'){
						if(indexText >0){
							sb.append(indexText+",");
							indexText = 0;
						}
						
						indexN ++;
					}else{
						if(indexN > 0){
							sb.append(indexN+",");
							indexN = 0;
						}
						
						indexText ++;
					}
					
				}
				
			return sb;
			}catch (Exception e) {
				// TODO: handle exception
			}
		return null;
	}
	
	/**
	 * 返回章节数
	 * 
	 * @param 
	 * 		fileName 文件名称
	 * @param 
	 * 		textCode 文件编码方式
	 * @return 
	 * 		返回 文章章节和对应起始位置的字节数
	 * 		每条数据形式为 【章节数,字节数】
	 * @throws IOException
	 */
	public static List<String> getText(String fileName,String textCode){
		
		//list初始大小
		int initListSize = 2*1000;
		List<String> chapterL = new ArrayList<String>(initListSize);
		
		try {
            
			int curByte;
			char ch;
			int tmpBufferSize;
			final int bufferSize = 10*1000;
			
			FileInputStream fInputStream = new FileInputStream(fileName);
			curByte = fInputStream.available();
			
			InputStreamReader inputStreamReader = new InputStreamReader(fInputStream, textCode);
			BufferedReader in = new BufferedReader(inputStreamReader);
			
			tmpBufferSize = bufferSize;
			
			StringBuffer sBuffer = new StringBuffer(tmpBufferSize);
			
			char buff[] = new char[curByte];
			in.read(buff, 0, curByte);
			for(int i=0; i < curByte; i++) {
				ch = buff[i];
				String str = String.valueOf(ch);
				sBuffer.append(str);
				
				if(i == tmpBufferSize){
					
					getChapter(sBuffer.toString(),chapterL,tmpBufferSize);
					
					tmpBufferSize+=bufferSize;
					sBuffer = null;
					sBuffer = new StringBuffer(bufferSize);
				}
				
				if(chapterL.size() == 50){
					break;
				}
			}
		 } catch (Exception e) {
	           e.printStackTrace();
         }
			return chapterL;
		}
	
	/**
	 * 
	 * @param str 
	 * 		被匹配的字符
	 * @param bufferL 
	 * 		结果储存位置
	 */
	private static void getChapter(String str,List<String> bufferL,int tmpBufferSize) {
		
		String matchStr = "第.{1,10}章\\s[^字数]{1,10}\\s";
//		String matchStr = "第.{1,4}章";
		
		Pattern p=Pattern.compile(matchStr);
		Matcher m=p.matcher(str);
		
		int tmpSize = tmpBufferSize - 10*1000;
		while(m.find()){
			String tmp = m.group()+","+(m.start()+tmpSize);
			bufferL.add(tmp);
		}
	}
}


 类似资料: