最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)文件切割拼接的實(shí)現(xiàn)代碼

 更新時(shí)間:2018年11月23日 14:26:08   作者:LudwigWuuu  
這篇文章主要介紹了Java實(shí)現(xiàn)文件切割拼接的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

單線程實(shí)現(xiàn)

文件分割

在老的FAT32文件系統(tǒng)中,最大的單個(gè)文件大小必須保存在4G內(nèi),對(duì)于經(jīng)??措娪暗奈疫@個(gè)是不能允許的。不過現(xiàn)在Windows有NTFS文件系統(tǒng),Linux大部分發(fā)行版為Ext4文件系統(tǒng),最大單個(gè)文件大小能大于4G。不過這二者并不能兼容。。格式化NTFS的U盤Linux不能識(shí)別,格式化Ext4的U盤Windows不能識(shí)別,只能用老的FAT32兼容二者。所以將文件分割,再進(jìn)行拼接就很重要,文件經(jīng)過分割了在網(wǎng)絡(luò)上傳輸就十分方便,也能開多線程對(duì)每部分進(jìn)行HASH提高處理效率。

最近看的BradPitt的《狂怒》

首先:對(duì)文件進(jìn)行分割需要確定每一部分的大小,假設(shè)上面的 Fury.mkv 文件大小為 280M ,分割每一塊設(shè)置默認(rèn)大小為 64M ,所以:

對(duì)于最后一塊,一般小于等于設(shè)定好的每塊默認(rèn)大小。 每塊大小設(shè)置好了,接下來,就需要將文件的路徑獲取,代碼中搭建輸入流,將文件讀入內(nèi)存緩沖區(qū)中,再搭建輸出流,將緩沖區(qū)輸出到新的分割文件中。 再接下來實(shí)現(xiàn)就很簡單了。 新建一個(gè) FileSlice

類:有切割方法,拼接方法。

public class FileSlice {
 /**
  * 分割文件
  * @param filePath 文件路徑
  * @param filePieceSize 文件每塊大小,單位為字節(jié),為-1則默認(rèn)為每塊64M
  * @return 成功返回True,出錯(cuò)則返回False
  */
 public static boolean slice(Path filePath, int filePieceSize){
  return true;
 }

 /**
  * 將分割好的文件重新鏈接
  * @param filePath 被分割好的其中之一文件路徑,默認(rèn)其他塊與其在同一目錄下
  * @param howManyParts 一共有多少塊
  * @return 成功返回True,出錯(cuò)則返回False
  */
 public static boolean glue(Path filePath, int howManyParts){
  return true;
 }
}

接下來實(shí)現(xiàn)單線程的分割方法: 用圖解的話應(yīng)該是這樣:

代碼實(shí)現(xiàn): 進(jìn)入函數(shù)首先判斷文件是否存在:

if (!Files.exists(filePath)){
 return false;
}

接下來判斷每塊大小是否使用默認(rèn)值:

if(filePieceSize == -1){
 filePieceSize = 1024*1024*64;
}

將路徑轉(zhuǎn)換為文件對(duì)象,再計(jì)算將分割多少塊:

File file = filePath.toFile();
int howManyParts = (int) Math.ceil(file.length() / (double)filePieceSize);

初始化輸入輸出流,出錯(cuò)輸出錯(cuò)誤信息,返回false,獲得當(dāng)前目錄:

DataInputStream fileReader = null;
try {
 fileReader = new DataInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
 e.printStackTrace();
 System.out.println("文件找不到!");
 return false;
}
DataOutputStream fileWriter;
Path dir = filePath.getParent();

接下來讀取文件,并且分別輸出到各個(gè)part文件中:

int readLength = -1;
long total = 0;

try {
 for (int i = 1; i <= howManyParts ; i++){
  //新建文件part i
  Path temp = Files.createFile(dir.resolve(filePath.getFileName() + ".part" + i));
  //搭建輸出流
  fileWriter = new DataOutputStream(new FileOutputStream(temp.toFile()));
  //讀取文件并輸出
  while ( (readLength = fileReader.read(buffer)) != -1){
   fileWriter.write(buffer,0,readLength);
   fileWriter.flush();
   total += readLength;
   if (total == filePieceSize){
    total = 0;
    break;
   }
  }
  //part i的文件已經(jīng)輸出完畢,關(guān)閉流
  fileWriter.close();
 }
 //讀取完畢,關(guān)閉輸入流
 fileReader.close();
} catch (IOException e) {
 e.printStackTrace();
 System.out.println("IO錯(cuò)誤!");
 return false;
}

該函數(shù)已經(jīng)實(shí)現(xiàn)完畢,接下來測試(由于電影Fury有14G。。太大了。。還是換個(gè)吧):

我是大哥大第5集,有729M,大概能分個(gè)12個(gè)part吧。

public static void main(String[] args) throws IOException {
 double before = System.currentTimeMillis();

 Path bigboss = Paths.get("D:\\Video\\我是大哥大\\我是大哥大.Kyou.kara.Ore.wa.Ep05.Chi_Jap.HDTVrip.1280X720.mp4");

 FileSlice.slice(bigboss,-1);

 double after = System.currentTimeMillis();

 System.out.println("分割文件我是大哥大.Kyou.kara.Ore.wa.Ep05.Chi_Jap.HDTVrip.1280X720.mp4," + Files.size(bigboss) + "字節(jié),總用時(shí)" + (after - before) + "ms" );

}

運(yùn)行結(jié)果:

分割文件我是大哥大.Kyou.kara.Ore.wa.Ep05.Chi_Jap.HDTVrip.1280X720.mp4,765321889字節(jié),總用時(shí)16335.0ms

速度還是挺慢的。。 下次還是換成多線程來實(shí)現(xiàn),再來測試下速度。在單線程情況下一個(gè)普通的40分鐘日劇都要15-30s左右,要是mkv格式的電影都要好久了。。不過其實(shí)極限應(yīng)該不在CPU中執(zhí)行的速度,而是在硬盤IO中,如果是普通硬盤那么就算是多線程也應(yīng)該提速不了多少。。

文件拼接

這個(gè)就很簡單了,和分割相反就OK。 直接上完整代碼:

public static boolean glue(Path filePath, int howManyParts){
 if (!Files.exists(filePath)){
  return false;
 }
 //獲取原始文件名
 String filename = getOriginalFileName(filePath.getFileName().toString());

 if (filename == null){
  System.out.println("傳入part文件名解析出錯(cuò)!");
  return false;
 }
 //初始化緩沖區(qū)
 byte [] buffer = new byte[1024 * 8];
 //獲取文件存儲(chǔ)的路徑
 Path dir = filePath.getParent();

 try {
  DataInputStream fileReader = null;
  //創(chuàng)建原始文件
  Files.createFile(dir.resolve(filename));
  //搭建原始文件輸出流
  DataOutputStream fileWriter = new DataOutputStream(new FileOutputStream(dir.resolve(filename).toFile()));

  int readLength = -1;
  for (int i = 1; i <= howManyParts ; i++){
   //得到part i文件路徑
   Path temp = dir.resolve(filename + ".part" + i);
   //搭建輸入流
   fileReader = new DataInputStream(new FileInputStream(temp.toFile()));
   //讀取文件并輸出
   while ( (readLength = fileReader.read(buffer)) != -1){
    fileWriter.write(buffer,0,readLength);
    fileWriter.flush();
   }
   //part i的文件已經(jīng)讀入完畢,關(guān)閉流
   fileReader.close();
  }
  //寫入完畢,關(guān)閉輸出流
  fileWriter.close();
 } catch (IOException e) {
  e.printStackTrace();
  System.out.println("IO錯(cuò)誤!");
  return false;
 }
 return true;
}

再測試剛剛分割好的我是大哥大第5集

public static void main(String[] args) throws IOException {
 double before = System.currentTimeMillis();

 Path bigboss = Paths.get("D:\\Video\\我是大哥大\\我是大哥大.Kyou.kara.Ore.wa.Ep05.Chi_Jap.HDTVrip.1280X720.mp4.part1");

 FileSlice.glue(bigboss,12);

 double after = System.currentTimeMillis();

 System.out.println("拼接12個(gè)part,用時(shí)" + (after - before) + "ms");

}

結(jié)果輸出,用12s左右,還行。

拼接12個(gè)part,用時(shí)12147.0ms

打開播放毫無問題,最后截張圖。

未完待續(xù)。。下次來使用多線程進(jìn)行實(shí)現(xiàn)。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Springboot指定掃描路徑的實(shí)現(xiàn)示例

    Springboot指定掃描路徑的實(shí)現(xiàn)示例

    本文主要介紹了Springboot指定掃描路徑的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Java中將MultipartFile和File互轉(zhuǎn)的方法詳解

    Java中將MultipartFile和File互轉(zhuǎn)的方法詳解

    我們在開發(fā)過程中經(jīng)常需要接收前端傳來的文件,通常需要處理MultipartFile格式的文件,今天來介紹一下MultipartFile和File怎么進(jìn)行優(yōu)雅的互轉(zhuǎn),需要的朋友可以參考下
    2023-10-10
  • MyBatis動(dòng)態(tài)SQL表達(dá)式詳解

    MyBatis動(dòng)態(tài)SQL表達(dá)式詳解

    動(dòng)態(tài)SQL可以省略很多拼接SQL的步驟,使用類似于JSTL方式,下面這篇文章主要給大家介紹了關(guān)于Mybatis動(dòng)態(tài)SQL特性的相關(guān)資料,文字通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Java實(shí)現(xiàn)FIFO功能的完整代碼實(shí)踐

    Java實(shí)現(xiàn)FIFO功能的完整代碼實(shí)踐

    在軟件開發(fā)中,隊(duì)列(Queue)是一種常見的數(shù)據(jù)結(jié)構(gòu),其特點(diǎn)是先進(jìn)先出(FIFO,First In First Out),FIFO 隊(duì)列在生產(chǎn)者-消費(fèi)者模型、任務(wù)調(diào)度、緩沖區(qū)管理等場景中具有廣泛的應(yīng)用,本文給大家介紹了Java實(shí)現(xiàn)FIFO功能的完整代碼實(shí)踐,需要的朋友可以參考下
    2025-03-03
  • SpringMVC實(shí)現(xiàn)文件的上傳和下載實(shí)例代碼

    SpringMVC實(shí)現(xiàn)文件的上傳和下載實(shí)例代碼

    本篇文章主要介紹了SpringMVC實(shí)現(xiàn)文件的上傳和下載實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • SpringBoot使用Redis方式

    SpringBoot使用Redis方式

    文章介紹了SpringDataRedis操作本地Redis數(shù)據(jù)庫的方法,包括Redis的基本概念、數(shù)據(jù)類型、命令以及在Java中的使用
    2024-11-11
  • 如何實(shí)現(xiàn)Java監(jiān)聽器詳解

    如何實(shí)現(xiàn)Java監(jiān)聽器詳解

    今天帶大家了解Java監(jiān)聽器是如何實(shí)現(xiàn)的及實(shí)現(xiàn)原理是什么,文中有非常詳細(xì)的說明,對(duì)正在學(xué)習(xí)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求

    java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求

    這篇文章主要為大家提供了java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求的相關(guān)代碼,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Eclipse/MyEclipse轉(zhuǎn)IntelliJ IDEA完全攻略(圖文)

    Eclipse/MyEclipse轉(zhuǎn)IntelliJ IDEA完全攻略(圖文)

    這篇文章主要介紹了Eclipse/MyEclipse轉(zhuǎn)IntelliJ IDEA完全攻略(圖文),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • MyBatis-Plus與PageHelper依賴的jsqlparser庫沖突

    MyBatis-Plus與PageHelper依賴的jsqlparser庫沖突

    在升級(jí)SpringBoot到3.x版本的同時(shí),升級(jí)MyBatis-Plus后發(fā)現(xiàn)PageHelper無法使用,原因是MyBatis-Plus和PageHelper都依賴jsqlparser庫,且PageHelper要求特定版本的jsqlparser,解決方法是在項(xiàng)目中排除這兩個(gè)庫的jsqlparser依賴,直接引用jsqlparser4.7版本
    2024-10-10

最新評(píng)論

永德县| 开封县| 蓬莱市| 岳阳市| 镇平县| 恩施市| 高陵县| 阳东县| 兴安盟| 郓城县| 河北省| 遂宁市| 辽宁省| 宜章县| 酉阳| 靖远县| 岳阳县| 鹿邑县| 南阳市| 台山市| 公安县| 融水| 锦屏县| 长岭县| 舒城县| 博兴县| 东乡县| 衢州市| 界首市| 五家渠市| 虎林市| 石门县| 乌鲁木齐县| 常宁市| 汉寿县| 吕梁市| 红原县| 海门市| 正阳县| 河北省| 额尔古纳市|