하나의 파일 크기를 계산하는 몇 가지 실현 방식

30016 단어 파일 크기
1. 직렬 계산
import java.io.File;



/**

 *     

 */

public class TotalFileSizeSequential {



    private long getTotalSizeOfFilesInDir(File file) {

        if(file.isFile())

            return file.length();

        

        long length = 0;

        File []children = file.listFiles();

        if(children != null)

            for(final File child : children) {

                length += getTotalSizeOfFilesInDir(child);

            }

        return length;

    }

    

    public static void main(String[] args) {

        final long start = System.nanoTime();

        final File file = new File("C:\\Windows");

        TotalFileSizeSequential total = new TotalFileSizeSequential();

        long size = total.getTotalSizeOfFilesInDir(file);

        final long end = System.nanoTime();

        System.out.println("total size:" + size);

        System.out.println("total token:"+(end - start) /1.0e9);

    }

}

2. 스레드 협업, 분자 작업, 새로운 스레드 시작(디렉터리가 깊지 않을 때 문제없음)
import java.io.File;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.TimeoutException;



/**

 *             ,            

 *             

 *

 */

public class NativelyConcurrentTotalFileSize {



    

    private long getTotalSizeOfFile(File file) throws InterruptedException, ExecutionException, TimeoutException {

        ExecutorService service = Executors.newFixedThreadPool(100);

        long size = getTotalSizeOfFilesInDir(service, file);

        return size;

    }

    

    private long getTotalSizeOfFilesInDir(final ExecutorService service, final File file) throws InterruptedException, ExecutionException, TimeoutException {

        if(file.isFile())

            return file.length();

        

        long size = 0;

        File []children = file.listFiles();

        if(children != null) {

            List<Future<Long>> futures = new ArrayList<Future<Long>>() ;

            for(final File child : children)

                futures.add(service.submit((new Callable<Long>() {

                        public Long call() throws Exception {

                            return getTotalSizeOfFilesInDir(service, child);

                        }

                    })

                ));

            

            for(Future<Long> future : futures) {

                size += future.get(10,TimeUnit.SECONDS);

            }

            return size;

        }

        return size;

        

    }



    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {

        final long start = System.nanoTime();

        final File file = new File("C:\\Windows");

        NativelyConcurrentTotalFileSize total = new NativelyConcurrentTotalFileSize();

        long size = total.getTotalSizeOfFile(file);

        final long end = System.nanoTime();

        System.out.println("total size:" + size);

        System.out.println("total token:"+(end - start) /1.0e9);

    }

}

3. 두 번째 방법에서 라인 잠금 시간이 초과되는 문제를 해결하고 폴더의 파일 크기와 메모리 하위 디렉터리를 계산할 때마다
import java.io.File;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.TimeoutException;



public class ConcurrentTotalFileSize {



    /**

     *           (        )

     */

    class SubDirectoriesAndSize {

        public long size;

        public List<File> subDirectories;

        public SubDirectoriesAndSize(final long size, final List<File> subDirectories) {

            this.size = size;

            this.subDirectories = Collections.unmodifiableList(subDirectories);

        }

    }

    

    /**

     *      

     */

    private long getTotalSizeOfFile(File file) throws InterruptedException, ExecutionException, TimeoutException {

        ExecutorService service = Executors.newFixedThreadPool(100);

        long size = getTotalSizeOfFilesInDir(service, file);

        return size;

    }

    

    /**

     *           

     */

    private SubDirectoriesAndSize getSubDirectoriesAndSize(final File file) {

        long total = 0;

        List<File> subDirectories = new ArrayList<File>();

        if(file.isDirectory()) {

            File []children = file.listFiles();

            if(children != null)

                for(final File child : children) {

                    if(child.isFile())

                        total += child.length();

                    else

                        subDirectories.add(child);

                }

        }

        return new SubDirectoriesAndSize(total, subDirectories);

    }

    

    private long getTotalSizeOfFilesInDir(ExecutorService service, File file) throws InterruptedException, ExecutionException, TimeoutException {

        if(file.isFile())

            return file.length();



        long size = 0;

        List<File> directories = new ArrayList<File>();

        directories.add(file);

        try {

            while(!directories.isEmpty()) {

                List<Future<SubDirectoriesAndSize>> futures = new ArrayList<Future<SubDirectoriesAndSize>>() ;

                for(final File child : directories) {

                    futures.add(service.submit(new Callable<SubDirectoriesAndSize>() {



                        @Override

                        public SubDirectoriesAndSize call() throws Exception {

                            return getSubDirectoriesAndSize(child);

                                

                        }

                    }));

                }

                directories.clear();//       

                

                for(Future<SubDirectoriesAndSize> future : futures) {

                    size += future.get().size;

                    directories.addAll(future.get(100,TimeUnit.SECONDS).subDirectories);

                }

            }

        } finally {

            service.shutdown();

        }

        

        return size;

    }





    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {

        final long start = System.nanoTime();

        final File file = new File("C:\\Windows");//       

        ConcurrentTotalFileSize total = new ConcurrentTotalFileSize();

        long size = total.getTotalSizeOfFile(file);

        final long end = System.nanoTime();

        System.out.println("total size:" + size);

        System.out.println("total token:"+(end - start) /1.0e9);

    }

    

}

4. 데이터 교환, Array BlockingQueue를 사용하여 온라인 거리에서 여러 그룹의 데이터를 상호 발송
import java.io.File;

import java.util.concurrent.ArrayBlockingQueue;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.TimeoutException;

import java.util.concurrent.atomic.AtomicLong;



/**

 *     

 *   ArrayBlockingQueue,          

 */

public class ConcurrentTotalFileSizeWQueue {



    private ExecutorService service;

    final private BlockingQueue<Long> fileSizes = new ArrayBlockingQueue<Long>(500);//       

    final private AtomicLong pendingFileVisits = new AtomicLong();



    private long getTotalSizeOfFile(File file) throws InterruptedException {

        service = Executors.newFixedThreadPool(100);

        try {

            startExploreFile(file);

            long totalSize = 0;

            while(pendingFileVisits.get() > 0 || fileSizes.size() > 0) {

                final long size = fileSizes.poll(10, TimeUnit.SECONDS);

                totalSize += size;

            }

            return totalSize;

        } finally {

            service.shutdown();

        }

    }



    private void startExploreFile(final File file) {

        pendingFileVisits.incrementAndGet();

        service.execute(new Runnable() {

            

            public void run() {

                exploreDir(file);

            }



        });

    }

    

    private void exploreDir(final File file) {

        long fileSize = 0;

        if(file.isFile())

            fileSize = file.length();

        else {

            File[] children = file.listFiles();

            if(children != null) {

                for(File child : children) {

                    if(child.isFile())

                        fileSize += child.length();

                    else

                        startExploreFile(child);

                }

            }

        }

        

        try {

            fileSizes.put(fileSize);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        

        pendingFileVisits.decrementAndGet();

    }



    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {

        final long start = System.nanoTime();

        final File file = new File("C:\\Windows");//       

        ConcurrentTotalFileSizeWQueue total = new ConcurrentTotalFileSizeWQueue();

        long size = total.getTotalSizeOfFile(file);

        final long end = System.nanoTime();

        System.out.println("total size:" + size);

        System.out.println("total token:"+(end - start) /1.0e9);

    }

}

5, CountDownLatch 구현, 결과를 반환하지 않음, 공유 상태, 코드 간결
/**

 * CountDownLatch   

 *           ,AtomicLong            long           

 * java.util.concurrent.atomic                              

 */

public class ConcurrentTotalSizeWLatch {



    private ExecutorService service;

    private AtomicLong pendingFileVisits = new AtomicLong();//               (    )   

    private AtomicLong totalSize = new AtomicLong();//    

    private CountDownLatch  latch = new CountDownLatch(1);

    private long getTotalSizeOfFile(File file) {

        service = Executors.newFixedThreadPool(100);

        pendingFileVisits.incrementAndGet();

        updateTotalSizeOfFileInDir(file);

        try {

            latch.await(100, TimeUnit.SECONDS);//        latch  0,           

        } catch (InterruptedException e) {

            e.printStackTrace();

        } finally {

            service.shutdown();

        }

        return totalSize.longValue();

    }

    

    private void updateTotalSizeOfFileInDir(File file) {

        long fileSize = 0;

        if(file.isFile())

            fileSize = file.length();

        

        if(file.isDirectory()) {

            File[] children = file.listFiles();

            if(children != null) {

                for(final File child : children) {

                    if(file.isFile())

                        fileSize += child.length();

                    else {

                        pendingFileVisits.incrementAndGet();

                        service.execute(new Runnable() {

                            public void run() {

                                updateTotalSizeOfFileInDir(child);

                            }

                        });

                    }

                        

                }

            }

        }

        totalSize.addAndGet(fileSize);

        

        if(pendingFileVisits.decrementAndGet() == 0) latch.countDown();//     

    }



    public static void main(String[] args) {

        final long start = System.nanoTime();

        final File file = new File("C:\\Windows");

        ConcurrentTotalSizeWLatch total = new ConcurrentTotalSizeWLatch();

        long size = total.getTotalSizeOfFile(file);

        final long end = System.nanoTime();

        System.out.println("total size:" + size);

        System.out.println("total token:"+(end - start) /1.0e9);

    }

이 학습 내용은 이라는 책에서 나온 것입니다.

좋은 웹페이지 즐겨찾기