Android 网络字幕文件保证编码一致的文件读写

本文介绍了一种在Android中处理网络字幕文件的方法,确保读写过程中编码的一致性。首先,通过URL.openStream()从网络获取InputStream,接着使用InputStreamReader和指定的字符集进行读取,以保持原始编码。然后,利用BufferedReader进行高效读取,并通过OutputStreamWriter以相同编码写入本地文件。最后,关闭所有相关流。同时,文章提及了如何识别文件编码,通常基于文件头几个字符进行判断。
摘要由CSDN通过智能技术生成

这是一段读入网络字幕文件并写出在本地的code。

<span style="font-size:24px;">    private String writeToLocalPath(String url){
        String tmpPath = null;
        String subtitleLocalPath = null;
        if (Tools.isSambaPlaybackUrl(url)) {
            Log.i(TAG,"HttpBean.setmSmbUrl url:"+url);
            HttpBean.setmSmbUrl(url);
            Log.i(TAG,"before convertSambaToHttpUrl's imagePath:"+url);
            String sambaPath = HttpBean.convertSambaToHttpUrl(url);
            Log.i(TAG,"convertSambaToHttpUrl's result sambaPath:"+sambaPath);
            tmpPath = sambaPath;
        } else {
            tmpPath = url;
        }
        final String realPath  = tmpPath;
        if (Tools.isNetPlayback(realPath)) {
            try {
                is = new URL(realPath).openStream();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            try {
                File mFile = new File(realPath);
                is = new FileInputStream(mFile);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        if (is == null) {
            Log.i(TAG,"is is null");
            return null;
        }
        String charset = GetCharset(realPath);
        try {
        mInputStreamReader = new InputStreamReader(is,charset);
            }catch (Exception e) {
                e.printStackTrace();
            }
        // One line read

        try {
            mBufferedReader = new BufferedReader(mInputStreamReader);
            char byteArray [] = new char[1024*8+1];
            int readNum = 0;
            int offset = 0;

            int index = realPath.lastIndexOf(".");
            String postFix = realPath.substring(index,realPath.length());
            subtitleLocalPath = "/data/subtitle"+postFix;
            File outPutLocalSubtitleFile = new File(subtitleLocalPath);
            mOutputStreamWriter = new OutputStreamWriter(new FileOutputStream(outPutLocalSubtitleFile),charset);
            mBufferedWriter = new BufferedWriter(mOutputStreamWriter);
            while ((readNum = mBufferedReader.read(byteArray,0,1024*8))>0){
                mBufferedWriter.write(byteArray,0,readNum);
                offset += readNum;
                Log.i(TAG,"andrew_read_write:"+readNum+","+offset);
            }

            mBufferedReader.close();
            mBufferedWriter.close();
            mInputStreamReader.close();
            mOutputStreamWriter.close();
            if (is!=null) {
                is.close();
            }
            if (isForGetCharset!=null) {
                isForGetCharset.close();
            }
        } catch (FileNotFoundException e){
            e.printStackTrace();

        } catch (IOException e){
            e.printStackTrace();
        }
        try {
              String command = "chmod 777 " + subtitleLocalPath;
              Log.i(TAG, "command = " + command);
              Runtime runtime = Runtime.getRuntime();
              Process proc = runtime.exec(command);
        } catch (IOException e) {
              Log.i(TAG,"chmod fail!!!!");
              e.printStackTrace();
        }
        return subtitleLocalPath;
    }</span>


通过

<span style="font-size:24px;">    public String GetCharset(final String filePath) {
        String charset = "GBK";
        byte[] first3Bytes = new byte[3];
        try {
            boolean checked = false;
            if (bis != null) {
                bis.close();
            }
            if (Tools.isNetPlayback(filePath)) {
                try {
                    isForGetCharset = new URL(filePath).openStream();
                } catch (MalformedURLException e) {
                     e.printStackTrace();
                } catch (IOException e) {
                     e.printStackTrace();
                }
                if (isForGetCharset == null) {
                    Log.i(TAG,"isForGetCharset is null");
                    return null;
                }
                bis = new BufferedInputStream(isForGetCharset);
            } else {
                File file = new File(filePath);
                bis = new BufferedInputStream(new FileInputStream(file));
            }
            // bis.mark(0);
            int read = bis.read(first3Bytes, 0, 3);
            if (read == -1)
                return charset;
            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = "UTF-16LE";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE
                    && first3Bytes[1] == (byte) 0xFF) {
                charset = "UTF-16BE";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xEF
                    && first3Bytes[1] == (byte) 0xBB
                    && first3Bytes[2] == (byte) 0xBF) {
                charset = "UTF-8";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFF
                    && first3Bytes[1] == (byte) 0xFE) {
                charset = "unicode";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0x5B
                    && first3Bytes[1] == (byte) 0x30) {
                charset = "ISO8859-1";
                checked = true;
            } else {
                charset = "GBK";
                checked = true;
            }
            // bis.reset();
            if (!checked) {
                while ((read = bis.read()) != -1) {
                    if (read >= 0xF0)
                        break;
                    if (0x80 <= read && read <= 0xBF)
                        break;
                    if (0xC0 <= read && read <= 0xDF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF)
                            continue;
                        else
                            break;
                    } else if (0xE0 <= read && read <= 0xEF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                charset = "UTF-8";
                                break;
                            } else
                                break;
                        } else
                            break;
                    }
                }
            }
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                bis.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        return charset;
    }</span>


(1)首先获取网络文件的文件流

主要是通过OpenStream获取到InputStream对象

        if (Tools.isNetPlayback(realPath)) {
            try {
                is = new URL(realPath).openStream();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            try {
                File mFile = new File(realPath);
                is = new FileInputStream(mFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
(2)为了加快读写速度使用字符读写器,需要使用字节流转字符流的转化类:InputStreamReader

使用获取到文件的编码来初始化对象,这样才能保证按照文件的真正编码方式读出来。

try {
        mInputStreamReader = new InputStreamReader(is,charset);
      }    catch (Exception e) {
                e.printStackTrace();
      }

(3)用InputStreamReader对象初始化一个字符读入类对象

mBufferedReader = new BufferedReader(mInputStreamReader);


(4)创建一个字符写出类对象

先根据本地路径创建文件,然后用文件创建字节写出类对象,然后使用读写文件时缓存下来的编码方式

以此来初始化字符写出类对象

    subtitleLocalPath = "/data/subtitle"+postFix;
            File outPutLocalSubtitleFile = new File(subtitleLocalPath);
            mOutputStreamWriter = new OutputStreamWriter(new FileOutputStream(outPutLocalSubtitleFile),charset);


(5)然后就可以边读边写文件了

读入多少字符,就写出多少字符。

while ((readNum = mBufferedReader.read(byteArray,0,1024*8))>0){
                mBufferedWriter.write(byteArray,0,readNum);
                offset += readNum;
                Log.i(TAG,"andrew_read_write:"+readNum+","+offset);
            }


(6)最后close掉字符流,字节流

mBufferedReader.close();
            mBufferedWriter.close();
            mInputStreamReader.close();
            mOutputStreamWriter.close();
            if (is!=null) {
                is.close();
            }
            if (isForGetCharset!=null) {
                isForGetCharset.close();
            }


(7)再说下怎么识别文件编码:

主要是根据文件的头三个字符进行分类判断。

不过网上应该有很多这样的例子,随便抄QAQ


结尾附上一篇总结的不错的文章:http://blog.csdn.net/lanhuzi9999/article/details/31389963

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值