国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java文件斷點續(xù)傳

這篇具有很好參考價值的文章主要介紹了Java文件斷點續(xù)傳。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Java文件斷點續(xù)傳

斷點續(xù)傳實現(xiàn)思路:將大文件均分成幾塊后,每個線程分別處理一塊數(shù)據(jù)的讀取和寫入。每次寫入都要更新記錄的日志文件,斷網(wǎng)或暫定后重新開始傳輸時,根據(jù)日志文件的信息,可以接著讀取寫入數(shù)據(jù),不用重頭開始傳輸。文章來源地址http://www.zghlxwxcb.cn/news/detail-519652.html

package com.demo;

import java.io.*;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/**
 * @descpription: 文件斷點續(xù)傳
 * @date 2023/3/4
 */
public class RandomAccessFileDemo {

    /**
     * 指定線程數(shù)
     */
    private static final Integer THREAD_NUM = 2;

    public static void main(String[] args) {
        String sourceStr = "~/Downloads/視頻/視頻.zip";
        String targetStr = "~/Desktop/視頻123.zip";
        breakpointResume(sourceStr,targetStr);
    }

    /**
     * 斷點續(xù)傳
     *
     * @param sourceStr   目標文件地址
     * @param targetStr 存放地址
     */
    public static void breakpointResume(String sourceStr, String targetStr) {
        File dataFile = new File(sourceStr);
        long length = dataFile.length();
        //每個線程均分文件大小,且向上取整
        long part = (long) Math.ceil(length / THREAD_NUM);
        //線程減法計數(shù)器
        CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
        Instant beginTime = Instant.now();
        //記錄傳輸?shù)娜罩疚募?/span>
        File logFile = new File(targetStr + ".log");
        String[] splitData = null;//不是null就需要斷點續(xù)傳
        BufferedReader reader = null;
        try {
            if (logFile.exists()) {
                //存在日志文件,需要進行斷點續(xù)傳
                reader = new BufferedReader(new FileReader(logFile));
                String data = reader.readLine();
                splitData = data.split(",");
            } else {
                //不存在日志文件,創(chuàng)建日志文件
                logFile.createNewFile();
            }
            Map<Integer, Long> maps = new ConcurrentHashMap<>();
            for (int i = 0; i < THREAD_NUM; i++) {
                final int k = i;
                System.out.println("線程正在執(zhí)行任務:" + k);
                String[] finalData = splitData;
                new Thread(() -> {
                    RandomAccessFile inFile = null;
                    RandomAccessFile outFile = null;
                    RandomAccessFile rafLog = null;
                    try {
                        inFile = new RandomAccessFile(dataFile, "r");//讀
                        outFile = new RandomAccessFile(targetStr, "rw");//寫
                        rafLog = new RandomAccessFile(logFile, "rw");//操作日志文件的流
                        //確定每個線程讀取文件的開始和結(jié)束的位置,有斷點續(xù)傳就從日志文件取出的位置開始讀取
                        inFile.seek(finalData == null ? k * part : Long.parseLong(finalData[k]));//設置每個線程讀取的啟始位置
                        outFile.seek(finalData == null ? k * part : Long.parseLong(finalData[k]));//設置每個線程寫入的啟始位置
                        byte[] bytes = new byte[1024 * 10];//每次讀取字節(jié)大小
                        int len = -1, allLen = 0;
                        while (true) {
                            len = inFile.read(bytes);//從磁盤讀取到緩存
                            if (len == -1) { //數(shù)據(jù)讀完,結(jié)束
                                break;
                            }
                            //如果不等于 -1,把每次讀取的字節(jié)累加
                            allLen = allLen + len;
                            //將讀取的字節(jié)數(shù)放入到map中
                            maps.put(k, allLen + (finalData == null ? k * part : Long.parseLong(finalData[k])));//每個線程的絕對偏移量
                            outFile.write(bytes, 0, len);//從緩存寫入到磁盤
                            //將map中的字節(jié)日志信息數(shù)據(jù)寫入磁盤
                            StringJoiner stringJoiner = new StringJoiner(",");
                            maps.forEach((key, value) -> stringJoiner.add(String.valueOf(value)));
                            //將日志信息寫入磁盤
                            rafLog.seek(0);//覆蓋之前的日志信息
                            rafLog.write(stringJoiner.toString().getBytes("UTF-8"));
                            /**
                             * 當前線程讀取的內(nèi)容
                             *  allLen + (k * part)
                             *  或
                             *  allLen + finalData[k] 日志文件里面的偏移量
                             *  >=
                             *  下個線程的起始部分((k + 1) * part)
                             *  當前線程就不再讀取寫入數(shù)據(jù),結(jié)束任務
                             */
                            if (allLen + (finalData == null ? k * part : Long.parseLong(finalData[k])) >= (k + 1) * part) {
                                break;
                            }
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        //關流
                        if (null != outFile && null != inFile && null != rafLog) {
                            try {
                                outFile.close();
                                inFile.close();
                                rafLog.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        countDownLatch.countDown();//減一
                    }
                }).start();
            }

            //主線程要等到線程計數(shù)器歸零,再繼續(xù)往下執(zhí)行
            countDownLatch.await();
            Instant endTime = Instant.now();
            System.out.println("總耗時:" + (Duration.between(beginTime, endTime).toMillis()) + "毫秒");
            //刪除日志文件
            logFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

到了這里,關于Java文件斷點續(xù)傳的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包