2011年11月21日星期一

Windows Live SkyDrive 的批次下載問題 2 (Batch download files in Windows Live SkyDrive 2)

自從 Microsoft 更新了 Windows Live SkyDrive 後
每次上載的檔案由每個 50MB 增加至每個 100MB,而下載速度相當快,平均有 2~3Mbps
但上載速度便不敢恭維了,3 個 100MB 檔案便會發生 Timeout,看來 SkyDrive 仍有進步空間
但在此文章,主要不是討論這些問題

SkyDrive 更新後,令 Windows Live SkyDrive 的批次下載問題 一同失效
因為 SkyDrive 的下載設計改變了,但仍有方法可以進行批次下載

前往 SkyDrive 檔案目錄
畫面右方會有「摘要」的超連結,點擊進入「摘要」後,會顯示一個 XML 文件
可查看該檔案目錄中的資料,當中需要知道的是「link」的標籤
例如 https://skydrive.live.com/self.aspx/.Public/iso/myiso.iso?cid=mycid (這只是例子,並非有效連結)
利用 HTTP 等下載工具將這連結下載
由於連結使用 https ,若使用 wget 下載需要加上 --no-check-certificate
下載檔案後,檢查檔案中一段字串,字串起首為「http:」結尾為「?download&psid=1
若文字編輯工具具有 Regex 搜尋工具 (如 Notepad++),可以搜尋「https[:].*[?]download[&]psid[=]1
(通常大約會在第 186 行附近)
另外 SkyDrive 會使用反斜線跳脫字元,因此下載該檔案前要先將反斜線清除
確定將所有「雜訊」處理掉後,餘下的連結便是該檔案的儲存位置

使用 Java 讀取網頁
public static final String DOWNLOAD_PREFIX = "https:";
public static final String DOWNLOAD_SUFFIX = "?download&psid=1";

String string = getURL(new URL("https://skydrive.live.com/self.aspx/.Public/iso/myiso.iso?cid=mycid"));

public static String getURL(URL url) throws IOException {
    String string = null;
    URLConnection con = url.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    for (String line; string == null && (line = in.readLine()) != null;) {
        int start = line.indexOf(DOWNLOAD_PREFIX);
        int end = line.indexOf(DOWNLOAD_SUFFIX);
        if (end > start && start > -1) {
// get the download link from line and remove \ characters
            string = line.substring(start, end + DOWNLOAD_SUFFIX.length()).replaceAll("\\\\", "");
        }
    }
    in.close();
    return string;
}

使用 Java 下載檔案
String string = getURL(new URL("https://skydrive.live.com/self.aspx/.Public/iso/myiso.iso?cid=mycid"));
getFile(new URL(string), new File("myiso.iso"));

public static void getFile(URL url, File file) throws IOException {
    URLConnection con = url.openConnection();
    InputStream is = con.getInputStream();
    FileOutputStream fos = new FileOutputStream(file);
    byte[] buffer = new byte[1024]; // you can modify the size of byte array
    for (int length; (length = is.read(buffer)) > 0;) {
        fos.write(buffer, 0, length);
    }
    fos.flush();
    fos.close();
    is.close();
}

沒有留言 :

發佈留言