http下载视频文件遇到的问题记录

先放调试好的代码

 /**
     * 从网络Url中下载文件
     *
     * @param urlStr   视频文件路径
     * @param fileName    本地生成的视频文件名称
     * @param savePath    本地生成的视频文件保存路径
     */
    public File downLoadFromUrl(String urlStr, String fileName, String savePath) {
        File file = null;
        try {
            logger.info("准备下载文件["+fileName+"]...");
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            logger.info("已和["+urlStr+"]建立连接...");
            // 设置超时间为10秒。
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(10000);

            // 防止屏蔽程序抓取而返回403错误
            conn.setRequestProperty(
                    "User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            logger.info("["+urlStr+"]准备获取返回...");
            // 得到输入流
            InputStream inputStream = conn.getInputStream();
            logger.info("["+urlStr+"]取得返回的输入流 || " + inputStream);
            int count = 0;
            int idx = 0;
            count = conn.getContentLength();
            /*while (idx < 10) {
                idx++;
                try {
                    count = inputStream.available();
                } catch (Exception ex) {
                    logger.info("获取字节数异常:", ex);
                }
                if (count == 0) {
                    Thread.sleep(240);
                } else {
                    Thread.sleep(120);
                }
            }*/
            logger.info("取得的字节数:" + count);
            // 获取自己数组
            byte[] getData = readBytesContent(inputStream, count);

            logger.info("获取视频数据流长度:" + (getData != null ? getData.length : "未获取到视频数据"));
            // 文件保存位置
            file = getFileByBytesAndResturn(getData, savePath, fileName);

            logger.info("info:" + url + " download success");
        } catch (Exception ex) {
            logger.error("获取视频异常["+fileName+"]:", ex);
        }
        return file;
    }

  	 /**
      * 输入流的字节数据读取
      * @param input    输入流
      * @param bytesLength    输入流总的字节长度
      * @return
      * @throws Exception
      */
    private byte[] readBytesContent(InputStream input,int bytesLength) throws Exception {
        logger.info("准备转换成字节数组...");
            int bytesRead = 0;
            int n = 0;
            int leftbytes = bytesLength;
            byte[] in_b = new byte[bytesLength];
            while (leftbytes > 0
                    && (n = input.read(in_b, bytesRead, leftbytes)) != -1) {
                    bytesRead = bytesRead + n;
                    leftbytes = bytesLength - bytesRead;
                }
            return in_b;
    }

	/**
     * 将Byte数组转换成文件并返回
     *
     * @param bytes
     * @param filePath   文件保存路径
     * @param fileName   文件名称
     * @return
     * 
     */
    public File getFileByBytesAndResturn(byte[] bytes, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists()) {// 判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath + "\\" + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (Exception e) {
            logger.error("生成文件异常:", e);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    logger.error("关闭BufferedOutputStream异常:", e);
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    logger.error("关闭FileOutputStream异常:", e);
                }
            }
        }
        return file;
    }

我是把这个方法放到线程里的,一开始使用的是不获取输入流中的字节长度,直接读取的输入流,但是实际使用的时候有时会出现线程阻塞的问题。

/**
     * 从输入流中获取字节数组
     * 这种方法在线程里使用,有时会出现线程阻塞,导致出现有的文件下载不下来的问题
     *
     * @param inputStream
     * @return
     * @throws Exception
     */
    public byte[] readInputStream(InputStream inputStream) throws Exception {
        logger.info("准备转换成字节数组...");
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

获取输入流的字节长度用conn.getContentLength();方法获取到的是完整的,一开始使用的是inputStream.available();方法、但是这个方法获取网络文件的大小不好用,后改为的conn.getContentLength()。

还有超时时间的设置,连接超时和读取超时都要设置,一开始只设置了连接超时也有点小问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
 CopyDVD.VCD是一款主要用于DVD/VCD光盘文件复制的实用工具,它支持单个或多个文件的复制,具有速度快、界面美观、操作方便等特点。 ●时实监控文件的复制状态(例如:已用时间、估计消耗、存取速度等)。  ●具有较高的文件读取及纠错能力,能读取损坏的文件,将损失降到最小。  ●当目标文件存在时,你可以选择删除、覆盖、合并成同一文件、以追加方式继续复制文件、重命名文件,断点续拷文件。 ●当目标文件存在坏块不能读取时,可自动跳过难读的坏块,继续复制文件。  ●当盘片质量存在坏块不能读取时,你可以设置读取或设置跳过的块数,以减轻光驱的负担,延长光驱的寿命。  ●具有多光驱管理能力,可以弹出和关闭所有光驱,可以弹出和关闭指定光驱。鼠标右击主窗体中的单选按钮,弹出多光驱控制快捷菜单。  ●具有断点续拷功能,在拷贝大文件时不需要担心发生死机、停电等意外情况,节约了大量的时间。 ●具有文件搜索功能,帮助你方便查找你所需要的视频、音频或其他文件。 ●具有文件拖放功能,你可以拖放单个或多个文件添加到文件列表,若遇文件名重复将自动清除重名的文件。 ●具有音频、视频文件预览功能[不支持DVD文件(*.VOB)的预览]。 ●文件或文件夹操作日志窗口帮助你轻松查看在复制文件的过程中遇到的错误,以及记录你在资源管理器里对文件/文件夹等进行的一系列操作。 ●鼠标右击主窗体的标题栏或文件组合列表框,弹出快捷菜单以帮助你对选定的文件进行一系列辅助操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值