1. 程式人生 > >怎麼用Java從網上下載一個視訊下來

怎麼用Java從網上下載一個視訊下來

用Java的IO流從網上下載一個視訊

原理:就是用URL物件與目標地址建立一個連結,用IO流的方式從這個連結上把視訊的二進位制資料讀取下載然後再寫入本地檔案。

程式碼思路

  1. 先建立一個連結物件,獲取到網頁的連結;
  2. 從連結物件獲取到輸入流,讀取資料;
  3. 建立一個輸出流,向本地檔案寫入資料。

程式碼實現

獲取連結物件

public class download {
    //定義一個HttpURLConnection在外面,因為要在finally中關閉
    HttpURLConnection connection = null;
    public static void main(String[] args) {
        try {
            //獲取連結物件
            URL url = new URL(videoUrl);
            HttpURLConnection connection = url.openConnection();
            connection.setRequestProperty("Range","bytes=0-");
            connection.connect();
            if(connection.getResponseCode() / 100 != 2){
                System.out.println("連結資源失敗...");
                return;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } finally {
            HttpURLConnection.disconnect();
        }
    }
} 

好了,現在來講一下上面的程式碼的作用:

1.URL url = new URL(videoUrl);就是獲取URL的資源物件,傳入的字串就是對應的地址;2.HttpURLConnection connection = url.openConnection();是獲取連結物件,就是靠這個物件來獲取流;3.connection.setRequestProperty("Range","bytes=0-");Range代表讀取的範圍,bytes=0-代表從0位元組到最大位元組,意味著讀取所有資源4.connection.connect();與網頁建立李連結,連結成功後就可以獲得流;5.connection.getResponseCode() / 100 != 2這一個判斷代表的是,如果建立連結返回的相應程式碼是200到300間就為成功,否則連結失敗

獲取流實現:

InputStream inputStream = connection.getInputStream();
獲取流只需要一行程式碼,從連線物件直接get。

實現檔案的寫入:這裡採用的是RandomAccessFile這個的物件。

String fileName = url.getFile();
fileName = fileName.substring(fileName.lastIndexOf("/")+1);
RandomAccessFile randomAccessFile = new RandomAccessFile(fileName,"rw");
1.第一行程式碼是獲取檔名稱,這裡說明一下,根據這個url來看,我們獲取的fileName是/C79EBFF6107CE4389C33DC5901307461-20.mp4,意思是getFile獲取的是.com後面的路徑,所以我這裡用擷取字串的方式來把檔名獲取了,當然也可以自己設定隨機的檔名2.字串擷取3.建立檔案寫入物件

下面貼出完整的實現程式碼:

package download;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class DownloadVideo {
    
    private static String videoUrl = "http://aqiniu.tangdou.com/C79EBFF6107CE4389C33DC5901307461-20.mp4";
    private static final int MAX_BUFFER_SIZE = 1000000; 
    
    public static void main(String[] args) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        RandomAccessFile randomAccessFile = null;
        try {
            // 1.獲取連線物件
            URL url = new URL(videoUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Range", "bytes=0-");
            connection.connect();
            if(connection.getResponseCode() / 100 != 2) {
                System.out.println("連線失敗...");
                return;
            }
            // 2.獲取連線物件的流
            inputStream = connection.getInputStream();
            //已下載的大小
            int downloaded = 0;
            //總檔案的大小
            int fileSize = connection.getContentLength();
            String fileName = url.getFile();
            fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
            // 3.把資源寫入檔案
            randomAccessFile = new RandomAccessFile(fileName,"rw");
            while(downloaded < fileSize) {
                // 3.1設定快取流的大小
                byte[] buffer = null;
                if(fileSize - downloaded >= MAX_BUFFER_SIZE) {
                    buffer = new byte[MAX_BUFFER_SIZE];
                }else {
                    buffer = new byte[fileSize - downloaded];
                }
                // 3.2把每一次快取的資料寫入檔案
                int read = -1;
                int currentDownload = 0;
                long startTime = System.currentTimeMillis();
                while(currentDownload < buffer.length) {
                    read = inputStream.read();
                    buffer[currentDownload ++] = (byte) read;
                }
                long endTime = System.currentTimeMillis();
                double speed = 0.0;
                if(endTime - startTime > 0) {
                    speed = currentDownload / 1024.0 / ((double)(endTime - startTime)/1000);
                }
                randomAccessFile.write(buffer);
                downloaded += currentDownload;
                randomAccessFile.seek(downloaded);
                System.out.printf("下載了進度:%.2f%%,下載速度:%.1fkb/s(%.1fM/s)%n",downloaded * 1.0 / fileSize * 10000 / 100,speed,speed/1000);
            }
            
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                connection.disconnect();
                inputStream.close();
                randomAccessFile.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }
    
    public static void demo() {
        try {
            URL url = new URL(videoUrl);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
這裡在補充說明上面的程式碼,MAX_BUFFER_SIZE是我設定的快取大小,在註釋3.1那裡判斷當前剩餘的下載大小是否大於快取之,如果不大於就把快取的大小設為剩餘的。
while(currentDownload < buffer.length) {
    read = inputStream.read();
    buffer[currentDownload ++] = (byte) read;
}

這段程式碼是按照快取的大小,讀寫該大小的位元組。然後迴圈依次寫入快取的大小,直至結束。這樣的優勢在於,不用讓硬體頻繁的寫入,可以提高效率和保護硬碟吧

控制檯輸出結果:

下載了進度:11.59%,下載速度:388.0kb/s(0.4M/s)下載了進度:23.19%,下載速度:262.5kb/s(0.3M/s)下載了進度:34.78%,下載速度:261.0kb/s(0.3M/s)下載了進度:46.38%,下載速度:258.3kb/s(0.3M/s)下載了進度:57.97%,下載速度:260.0kb/s(0.3M/s)下載了進度:69.57%,下載速度:260.9kb/s(0.3M/s)下載了進度:81.16%,下載速度:257.4kb/s(0.3M/s)下載了進度:92.75%,下載速度:252.3kb/s(0.3M/s)下載了進度:100.00%,下載速度:286.5kb/s(0.3M/s)
好了,以上就是下載視訊的簡單實現,小弟也是剛學的,可能有許多地方不是很好,請不吝指教。