जावा में किसी फ़ाइल को कॉपी करने का मानक संक्षिप्त तरीका?


421

इसने मुझे हमेशा परेशान किया है कि जावा में किसी फाइल को कॉपी करने का एकमात्र तरीका स्ट्रीम खोलना, बफर घोषित करना, एक फाइल में पढ़ना, इसके माध्यम से लूप करना और इसे दूसरे स्टीम से लिखना है। वेब समान रूप से भरा हुआ है, फिर भी इस प्रकार के समाधान से थोड़ा अलग है।

वहाँ एक बेहतर तरीका है जो जावा भाषा की सीमा के भीतर रहता है (जिसका अर्थ है निष्पादन-विशिष्ट OS विशिष्ट कमांड शामिल नहीं है)? शायद कुछ विश्वसनीय ओपन सोर्स यूटिलिटी पैकेज में, जो कम से कम इस अंतर्निहित कार्यान्वयन को अस्पष्ट करेगा और एक लाइन समाधान प्रदान करेगा?


5
Apache Commons FileUtils में कुछ हो सकता है , विशेष रूप से, copyFile विधियाँ।
टूलकिट

22
: जावा 7 का उपयोग कर रहे हैं, तो Files.copy बजाय, के रूप में @GlenBest द्वारा सिफारिश का उपयोग stackoverflow.com/a/16600787/44737
लूटने

जवाबों:


274

जैसा कि टूलकिट में उल्लेख किया गया है, अपाचे कॉमन्स आईओ जाने का रास्ता है, विशेष रूप से फाइलयूटिल्सcopyFile () ; यह आप के लिए सभी भारी उठाने संभालती है।

और एक पोस्टस्क्रिप्ट के रूप में, ध्यान दें कि FileUtils के हाल के संस्करणों (जैसे 2.0.1 रिलीज़) ने फ़ाइलों की प्रतिलिपि बनाने के लिए NIO का उपयोग जोड़ा है; NIO एक बड़े हिस्से में फ़ाइल-कॉपी करने के प्रदर्शन को महत्वपूर्ण रूप से बढ़ा सकता है , क्योंकि NIO रूटीन जावा परत के माध्यम से बाइट्स को पढ़ने और लिखने के बजाय इसे सीधे OS / फाइल सिस्टम में कॉपी करता है। इसलिए यदि आप प्रदर्शन की तलाश कर रहे हैं, तो यह जाँचने योग्य हो सकता है कि आप फाइलयूलेट्स के हालिया संस्करण का उपयोग कर रहे हैं।


1
बहुत उपयोगी - क्या आपके पास कोई अंतर्दृष्टि है जब एक आधिकारिक रिलीज इन nio परिवर्तनों को शामिल करेगी?
पीटर

2
Apache Commons IO की सार्वजनिक रिलीज़ अभी भी 1.4 बजे, grrrrrrr
पीटर

14
दिसंबर 2010 तक, Apache Commons IO 2.0.1 पर है, जिसमें NIO कार्यक्षमता है। उत्तर अपडेट किया गया।
साइमन निकर्सन

4
एंड्रॉइड लोगों के लिए एक चेतावनी: यह मानक एंड्रॉइड एपीआई में शामिल नहीं है
IlDan

18
: जावा 7 या नए का उपयोग कर रहे हैं, तो आप के रूप में @GlenBest ने सुझाव दिया Files.copy उपयोग कर सकते हैं stackoverflow.com/a/16600787/44737
लूटने

278

मैं अपाचे कॉमन की तरह एक मेगा एपी के उपयोग से बचूंगा। यह एक सरलीकृत ऑपरेशन है और इसका निर्माण नए NIO पैकेज में JDK में किया गया है। यह एक पिछले उत्तर में पहले से ही जुड़ा हुआ था, लेकिन एनआईओ एपीआई में प्रमुख विधि नए फ़ंक्शन "ट्रांसफरटॉ" और "ट्रांसफरफ्रॉम" हैं।

http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html#transferTo(long,%20long,%20java.nio.channels.WritableByteChannel)

लिंक किए गए लेखों में से एक ट्रांसफ़ॉर्म का उपयोग करके इस फ़ंक्शन को अपने कोड में कैसे एकीकृत किया जाए, इस पर एक शानदार तरीका दिखाता है:

public static void copyFile(File sourceFile, File destFile) throws IOException {
    if(!destFile.exists()) {
        destFile.createNewFile();
    }

    FileChannel source = null;
    FileChannel destination = null;

    try {
        source = new FileInputStream(sourceFile).getChannel();
        destination = new FileOutputStream(destFile).getChannel();
        destination.transferFrom(source, 0, source.size());
    }
    finally {
        if(source != null) {
            source.close();
        }
        if(destination != null) {
            destination.close();
        }
    }
}

NIO सीखना थोड़ा मुश्किल हो सकता है, इसलिए आप दूर जाने से पहले इस मैकेनिक पर भरोसा करना चाहते हैं और रातोंरात NIO सीखने की कोशिश कर सकते हैं। व्यक्तिगत अनुभव से यह सीखना बहुत कठिन काम हो सकता है यदि आपके पास अनुभव नहीं है और IO को java.io स्ट्रीम के माध्यम से पेश किया गया है।


2
धन्यवाद, उपयोगी जानकारी। मैं अब भी अपाचे कॉमन्स जैसी किसी चीज के लिए बहस करूंगा, खासकर अगर यह नीओ (ठीक से) का उपयोग करता है; लेकिन मैं मानता हूं कि अंतर्निहित बुनियादी बातों को समझना महत्वपूर्ण है।
पीटर

1
दुर्भाग्य से, वहाँ caveats हैं। जब मैंने विंडोज 7, 32 बिट पर 1.5 जीबी फ़ाइल की प्रतिलिपि बनाई, तो यह फ़ाइल को मैप करने में विफल रहा। मुझे दूसरे उपाय की तलाश करनी थी।
एंटोन के।

15
उपरोक्त कोड के साथ तीन संभावित समस्याएं: (ए) यदि getChannel अपवाद फेंकता है, तो आप एक खुली स्ट्रीम लीक कर सकते हैं; (बी) बड़ी फ़ाइलों के लिए, आप ओएस को संभालने की तुलना में एक बार में अधिक स्थानांतरित करने की कोशिश कर सकते हैं; (c) आप ट्रांसफ़र के रिटर्न मान को अनदेखा कर रहे हैं, इसलिए यह फ़ाइल के सिर्फ एक हिस्से की नकल हो सकता है। यही कारण है कि org.apache.tools.ant.util.ResourceUtils.copyResource इतना जटिल है। यह भी ध्यान दें कि जबकि ट्रांसफ़ॉर्म ठीक है, स्थानांतरण लिनक्स पर JDK 1.4 पर टूटता है: Bugs.sun.com/bugdatabase/view_bug.do?bug_id=5056395
जेसी ग्लिक

7
मेरा मानना ​​है कि यह अद्यतन संस्करण उन चिंताओं को संबोधित करता है: gist.github.com/889747
मार्क

11
इस कोड में एक बड़ी समस्या है। TransferTo () को लूप में बुलाया जाना चाहिए। यह अनुरोध की गई पूरी राशि को हस्तांतरित करने की गारंटी नहीं देता है।
लोर्ने

180

अब जावा 7 के साथ, आप निम्नलिखित कोशिश-संसाधन-सिंटैक्स का उपयोग कर सकते हैं:

public static void copyFile( File from, File to ) throws IOException {

    if ( !to.exists() ) { to.createNewFile(); }

    try (
        FileChannel in = new FileInputStream( from ).getChannel();
        FileChannel out = new FileOutputStream( to ).getChannel() ) {

        out.transferFrom( in, 0, in.size() );
    }
}

या, बेहतर अभी तक, यह भी जावा 7 में पेश नई फ़ाइलें वर्ग का उपयोग कर पूरा किया जा सकता है:

public static void copyFile( File from, File to ) throws IOException {
    Files.copy( from.toPath(), to.toPath() );
}

बहुत snazzy, एह?


15
यह आश्चर्यजनक है कि जावा ने आज से पहले इस तरह की चीजों को नहीं जोड़ा है। कुछ संचालन कंप्यूटर सॉफ्टवेयर लिखने के लिए आवश्यक हैं। जावा के ओरेकल डेवलपर्स ऑपरेटिंग सिस्टम से एक या दो चीजें सीख सकते हैं, वे देख सकते हैं कि वे कौन सी सेवाएं प्रदान करते हैं, जिससे यह आसानी से माइग्रेट कर सकता है।
रिक हॉजिन

2
आह धन्यवाद! मुझे अपने सभी सहायक कार्यों के साथ नई "फाइलें" वर्ग के बारे में पता नहीं था। यह वही है जो मुझे चाहिए। उदाहरण के लिए धन्यवाद।
क्रिसकैंटरेल

1
प्रदर्शन के लिहाज से java NIO FileChannel बेहतर है, इस लेख को पढ़ें journaldev.com/861/4-ways-to-copy-file-in-java
Pankaj

5
इस कोड में एक बड़ी समस्या है। TransferTo () को लूप में बुलाया जाना चाहिए। यह अनुरोध की गई पूरी राशि को हस्तांतरित करने की गारंटी नहीं देता है।
लोर्ने

@ नोट: पीट ने एक-लाइन समाधान के लिए कहा और आप इतने करीब हैं ... यह एक CopyFile विधि में Files.copy को लपेटने के लिए अनावश्यक है। मैंने आपके उत्तर की शुरुआत में Files.copy (पथ से, पथ से) पर रखा था और उल्लेख किया था कि आप File.toPath () का उपयोग कर सकते हैं यदि आपके पास मौजूदा फ़ाइल ऑब्जेक्ट हैं: Files.copy (fromFile.toPath) () toFile.toPath ())
लूटने

89
  • ये तरीके प्रदर्शन-इंजीनियर हैं (वे ऑपरेटिंग सिस्टम देशी I / O के साथ एकीकृत करते हैं)।
  • ये विधियां फाइलों, निर्देशिकाओं और लिंक के साथ काम करती हैं।
  • आपूर्ति किए गए प्रत्येक विकल्प को छोड़ा जा सकता है - वे वैकल्पिक हैं।

उपयोगिता वर्ग

package com.yourcompany.nio;

class Files {

    static int copyRecursive(Path source, Path target, boolean prompt, CopyOptions options...) {
        CopyVisitor copyVisitor = new CopyVisitor(source, target, options).copy();
        EnumSet<FileVisitOption> fileVisitOpts;
        if (Arrays.toList(options).contains(java.nio.file.LinkOption.NOFOLLOW_LINKS) {
            fileVisitOpts = EnumSet.noneOf(FileVisitOption.class) 
        } else {
            fileVisitOpts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
        }
        Files.walkFileTree(source[i], fileVisitOpts, Integer.MAX_VALUE, copyVisitor);
    }

    private class CopyVisitor implements FileVisitor<Path>  {
        final Path source;
        final Path target;
        final CopyOptions[] options;

        CopyVisitor(Path source, Path target, CopyOptions options...) {
             this.source = source;  this.target = target;  this.options = options;
        };

        @Override
        FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        // before visiting entries in a directory we copy the directory
        // (okay if directory already exists).
        Path newdir = target.resolve(source.relativize(dir));
        try {
            Files.copy(dir, newdir, options);
        } catch (FileAlreadyExistsException x) {
            // ignore
        } catch (IOException x) {
            System.err.format("Unable to create: %s: %s%n", newdir, x);
            return SKIP_SUBTREE;
        }
        return CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        Path newfile= target.resolve(source.relativize(file));
        try {
            Files.copy(file, newfile, options);
        } catch (IOException x) {
            System.err.format("Unable to copy: %s: %s%n", source, x);
        }
        return CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        // fix up modification time of directory when done
        if (exc == null && Arrays.toList(options).contains(COPY_ATTRIBUTES)) {
            Path newdir = target.resolve(source.relativize(dir));
            try {
                FileTime time = Files.getLastModifiedTime(dir);
                Files.setLastModifiedTime(newdir, time);
            } catch (IOException x) {
                System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
            }
        }
        return CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        if (exc instanceof FileSystemLoopException) {
            System.err.println("cycle detected: " + file);
        } else {
            System.err.format("Unable to copy: %s: %s%n", file, exc);
        }
        return CONTINUE;
    }
}

निर्देशिका या फ़ाइल की प्रतिलिपि बनाना

long bytes = java.nio.file.Files.copy( 
                 new java.io.File("<filepath1>").toPath(), 
                 new java.io.File("<filepath2>").toPath(),
                 java.nio.file.StandardCopyOption.REPLACE_EXISTING,
                 java.nio.file.StandardCopyOption.COPY_ATTRIBUTES,
                 java.nio.file.LinkOption.NOFOLLOW_LINKS);

निर्देशिका या फ़ाइल ले जाना

long bytes = java.nio.file.Files.move( 
                 new java.io.File("<filepath1>").toPath(), 
                 new java.io.File("<filepath2>").toPath(),
                 java.nio.file.StandardCopyOption.ATOMIC_MOVE,
                 java.nio.file.StandardCopyOption.REPLACE_EXISTING);

किसी निर्देशिका या फ़ाइल को पुनरावर्ती रूप से कॉपी करना

long bytes = com.yourcompany.nio.Files.copyRecursive( 
                 new java.io.File("<filepath1>").toPath(), 
                 new java.io.File("<filepath2>").toPath(),
                 java.nio.file.StandardCopyOption.REPLACE_EXISTING,
                 java.nio.file.StandardCopyOption.COPY_ATTRIBUTES
                 java.nio.file.LinkOption.NOFOLLOW_LINKS );

फ़ाइलों के लिए पैकेज का नाम गलत था (java.nio.file नहीं java.nio होना चाहिए)। मैंने उसके लिए एक संपादन प्रस्तुत किया है; आशा है कि यह ठीक है!
स्टुअर्ट रॉसिटर

43

जावा 7 में यह आसान है ...

File src = new File("original.txt");
File target = new File("copy.txt");

Files.copy(src.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);

1
आपका जवाब स्कॉट या ग्लेन से क्या जोड़ता है?
उड़ी अगासी

11
यह संक्षिप्त है, कम अधिक है। उनके उत्तर अच्छे और विस्तृत हैं, लेकिन जब मैं देख रहा था तो मैं उनसे चूक गया। दुर्भाग्य से इसके बहुत सारे उत्तर हैं और उनमें से बहुत लंबे, अप्रचलित और जटिल हैं और स्कॉट और ग्लेन के अच्छे उत्तर उसी में खो गए हैं (मैं उस के साथ मदद करने के लिए upvotes दूंगा)। मुझे आश्चर्य है कि यदि मौजूद () और त्रुटि संदेश को खटखटाकर मेरे उत्तर को तीन पंक्तियों में कम करके सुधार किया जा सकता है।
केविन सैडलर

यह निर्देशिकाओं के लिए काम नहीं करता है। धिक्कार है सबको यह एक गलत हो रहा है। एपीआई संचार से अधिक आपकी गलती को जारी करता है। मैं भी गलत हो गया।
एमएमएम

2
@momo सवाल था कि किसी फाइल को कॉपी कैसे किया जाता है।
केविन सडलर

28

किसी फ़ाइल की प्रतिलिपि बनाने और उसे अपने गंतव्य पथ पर सहेजने के लिए आप नीचे दी गई विधि का उपयोग कर सकते हैं।

public void copy(File src, File dst) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dst);
        try {
            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}

1
यह काम करेगा, लेकिन मुझे नहीं लगता कि यह अन्य उत्तरों से बेहतर है?
रुप

2
@Rup यह अन्य उत्तरों की तुलना में काफी बेहतर है, (a) क्योंकि यह काम करता है, और (b) क्योंकि यह तीसरे सॉफ्टवेयर सॉफ्टवेयर पर निर्भर नहीं करता है।
लोर्ने

1
@ ईजेपी ठीक है, लेकिन यह बहुत स्मार्ट नहीं है। फाइल कॉपी एक ओएस या फाइलसिस्टम ऑपरेशन होना चाहिए, न कि एप्लिकेशन ऑपरेशन: जावा उम्मीद है कि एक कॉपी को स्पॉट कर सकता है और एक ओएस ऑपरेशन में बदल सकता है, जिसमें फाइल को स्पष्ट रूप से पढ़ने के अलावा आप उसे रोक रहे हैं। अगर आपको नहीं लगता कि जावा ऐसा कर सकता है, तो क्या आप भरोसा करेंगे कि यह 1K रीड्स और बड़े ब्लॉकों में लिखता है? और अगर स्रोत और गंतव्य एक धीमे नेटवर्क पर एक दूरस्थ हिस्से पर थे तो यह स्पष्ट रूप से गैर-जरूरी काम कर रहा है। हां कुछ थर्ड पार्टी JARs मूर्खतापूर्ण रूप से बड़े (अमरूद!) हैं, लेकिन वे इस तरह से बहुत सारे सामान जोड़ते हैं।
रूप

एक जादू की तरह काम किया। सर्वश्रेष्ठ समाधान जिसे 3 पार्टी लाइब्रेरी की आवश्यकता नहीं है और जावा 1.6 पर काम करता है। धन्यवाद।
जेम्स वियरज़बा

@ मैं मानता हूं कि यह एक ऑपरेटिंग सिस्टम फ़ंक्शन होना चाहिए, लेकिन मैं आपकी टिप्पणी का कोई अन्य अर्थ नहीं बना सकता। पहले बृहदान्त्र के बाद का हिस्सा कहीं एक क्रिया की कमी है; मैं न तो 'ट्रस्ट' की अपेक्षा करूँगा कि जावा 1k ब्लॉक को कुछ बड़े में बदल दे, हालाँकि मैं निश्चित रूप से अपने आप में बहुत बड़े ब्लॉक का उपयोग करूँगा; मैं कभी भी एक एप्लिकेशन नहीं लिखूंगा जो पहली बार साझा फ़ाइलों का उपयोग करता है; और मुझे इस बात की जानकारी नहीं है कि कोई भी तीसरा पक्ष पुस्तकालय इस कोड की तुलना में कुछ भी अधिक 'उचित' (आप जो भी मतलब है) करता है, सिवाय शायद एक बड़े बफर का उपयोग करने के।
लोर्ने का मार्किव

24

ध्यान दें कि ये सभी तंत्र केवल फ़ाइल की सामग्री की प्रतिलिपि बनाते हैं, न कि मेटाडेटा जैसे कि अनुमतियाँ। इसलिए यदि आप एक निष्पादन योग्य .sh फ़ाइल को लिनक्स पर कॉपी या स्थानांतरित करने के लिए थे, तो नई फ़ाइल निष्पादन योग्य नहीं होगी।

किसी फ़ाइल को वास्तव में कॉपी या स्थानांतरित करने के लिए, यानी कमांड लाइन से कॉपी करने के समान परिणाम प्राप्त करने के लिए, आपको वास्तव में एक देशी टूल का उपयोग करने की आवश्यकता होती है। या तो एक शेल स्क्रिप्ट या जेएनआई।

जाहिरा तौर पर, यह जावा 7 में तय किया जा सकता है - http://today.java.net/pub/a/today/2008/07/03/jsr-203-new-file-apis.html । उंगलियों को पार कर!


23

Google की अमरूद लाइब्रेरी में एक कॉपी विधि भी है :

सार्वजनिक स्थैतिक शून्य प्रति ( फ़ाइल  से
                         फ़ाइल  )IOException को 
                 फेंकता है
सभी बाइट्स को एक फाइल से दूसरी फाइल में कॉपी करता है।

चेतावनी: यदि toकिसी मौजूदा फ़ाइल का प्रतिनिधित्व करता है, तो वह फ़ाइल सामग्री से अधिलेखित हो जाएगी from। यदि toऔर उसी फ़ाइल fromको देखें , तो उस फ़ाइल की सामग्री हटा दी जाएगी।

पैरामीटर:from - स्रोत फ़ाइल to- गंतव्य फ़ाइल

फेंकता है: IOException - यदि I / O त्रुटि होती है IllegalArgumentException- यदिfrom.equals(to)


19

जावा 7 में मानक के रूप में उपलब्ध, path.copyTo: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path.html http://java.sun.com/docs/books/ ट्यूटोरियल / आवश्यक / कब / copy.html

मुझे विश्वास नहीं हो रहा है कि उन्हें फ़ाइल के नकल के रूप में कुछ सामान्य और सरल मानकीकृत करने में इतना समय लगा:


10
कोई Path.copyTo नहीं है; यह Files.copy है।
जेसी ग्लिक

7

उपरोक्त कोड के साथ तीन संभावित समस्याएं:

  1. यदि getChannel एक अपवाद फेंकता है, तो आप एक खुली स्ट्रीम लीक कर सकते हैं।
  2. बड़ी फ़ाइलों के लिए, आप एक बार में ओएस को संभालने की तुलना में अधिक स्थानांतरित करने का प्रयास कर सकते हैं।
  3. आप ट्रांसफ़र के रिटर्न मान को अनदेखा कर रहे हैं, इसलिए यह फ़ाइल के सिर्फ एक हिस्से की नकल हो सकता है।

यही कारण है कि org.apache.tools.ant.util.ResourceUtils.copyResourceयह इतना जटिल है। यह भी ध्यान दें कि जब ट्रांसफ़ॉर्म ठीक हो, तो ट्रांसफ़ॉर्मो JDK 1.4 पर लिनक्स पर टूट जाता है ( बग आईडी देखें : 5056395 ) - जेसी ग्लिक जान


7

यदि आप एक वेब एप्लिकेशन में हैं, जो पहले से ही स्प्रिंग का उपयोग करता है और यदि आप साधारण फाइल कॉपी के लिए Apache Commons IO को शामिल नहीं करना चाहते हैं, तो आप स्प्रिंग फ्रेमवर्क के FileCopyUtils का उपयोग कर सकते हैं ।


7

यहाँ तीन तरीके हैं जिनसे आप आसानी से कोड की एक लाइन के साथ फाइल कॉपी कर सकते हैं!

जावा 7 :

java.nio.file.Files # प्रतिलिपि

private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
    Files.copy(source.toPath(), dest.toPath());
}

अपाचे कॉमन्स आईओ :

FileUtils # CopyFile

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
    FileUtils.copyFile(source, dest);
}

अमरूद :

फ़ाइलें # प्रतिलिपि

private static void copyFileUsingGuava(File source,File dest) throws IOException{
    Files.copy(source,dest);          
}

पहले एक निर्देशिका के लिए काम नहीं करता है। धिक्कार है सबको यह एक गलत हो रहा है। एपीआई संचार से अधिक आपकी गलती को जारी करता है। मैं भी गलत हो गया।
एमएमएम

पहले एक को 3 पैरामीटर चाहिए। Files.copyकेवल 2 मापदंडों का उपयोग Pathकरने के लिए है Stream। बस पैरामीटर जोड़ें StandardCopyOption.COPY_ATTRIBUTESया StandardCopyOption.REPLACE_EXISTINGके PathलिएPath
पिंप ट्राइज़किट

6
public static void copyFile(File src, File dst) throws IOException
{
    long p = 0, dp, size;
    FileChannel in = null, out = null;

    try
    {
        if (!dst.exists()) dst.createNewFile();

        in = new FileInputStream(src).getChannel();
        out = new FileOutputStream(dst).getChannel();
        size = in.size();

        while ((dp = out.transferFrom(in, p, size)) > 0)
        {
            p += dp;
        }
    }
    finally {
        try
        {
            if (out != null) out.close();
        }
        finally {
            if (in != null) in.close();
        }
    }
}

तो ऊपर स्वीकार किए गए उत्तर से अंतर यह है कि आपको ट्रांसफर मिल गया है थोड़ी देर में?
रुप

1
संकलन भी नहीं करता है, और createNewFile () कॉल निरर्थक और बेकार है।
लोर्न

3

मेरे परीक्षण के अनुसार बफर के साथ एनआईओ कॉपी सबसे तेज है। Https://github.com/mhisoft/fastcopy पर मेरा एक परीक्षण परियोजना से नीचे काम कर कोड देखें

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;


public class test {

private static final int BUFFER = 4096*16;
static final DecimalFormat df = new DecimalFormat("#,###.##");
public static void nioBufferCopy(final File source, final File target )  {
    FileChannel in = null;
    FileChannel out = null;
    double  size=0;
    long overallT1 =  System.currentTimeMillis();

    try {
        in = new FileInputStream(source).getChannel();
        out = new FileOutputStream(target).getChannel();
        size = in.size();
        double size2InKB = size / 1024 ;
        ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER);

        while (in.read(buffer) != -1) {
            buffer.flip();

            while(buffer.hasRemaining()){
                out.write(buffer);
            }

            buffer.clear();
        }
        long overallT2 =  System.currentTimeMillis();
        System.out.println(String.format("Copied %s KB in %s millisecs", df.format(size2InKB),  (overallT2 - overallT1)));
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    finally {
        close(in);
        close(out);
    }
}

private static void close(Closeable closable)  {
    if (closable != null) {
        try {
            closable.close();
        } catch (IOException e) {
            if (FastCopy.debug)
                e.printStackTrace();
        }    
    }
}

}


अच्छा! यह एक
स्वसंपूर्ण

2

जावा के सभी संस्करणों के साथ एंड्रॉइड के तेज और काम:

private void copy(final File f1, final File f2) throws IOException {
    f2.createNewFile();

    final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
    final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");

    file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));

    file1.close();
    file2.close();
}

1
हालांकि सभी फाइल सिस्टम मेमोरी मैप्ड फ़ाइलों का समर्थन नहीं करते हैं, और मुझे लगता है कि यह छोटी फाइलों के लिए अपेक्षाकृत महंगा है।
रूप

1.4 से पहले जावा के किसी भी संस्करण के साथ काम नहीं करता है, और ऐसा कुछ भी नहीं है जो एकल लेखन की गारंटी देता है पर्याप्त है।
लोर्ने

1

पार्टी में थोड़ी देर हो गई है, लेकिन यहां विभिन्न फ़ाइल कॉपी विधियों का उपयोग करके फ़ाइल की प्रतिलिपि बनाने में लगने वाले समय की तुलना की गई है। मैंने 10 बार विधियों के माध्यम से पाला और औसत लिया। IO धाराओं का उपयोग करके फ़ाइल स्थानांतरण सबसे खराब उम्मीदवार लगता है:

विभिन्न तरीकों का उपयोग करके फ़ाइल स्थानांतरण की तुलना

ये तरीके हैं:

private static long fileCopyUsingFileStreams(File fileToCopy, File newFile) throws IOException {
    FileInputStream input = new FileInputStream(fileToCopy);
    FileOutputStream output = new FileOutputStream(newFile);
    byte[] buf = new byte[1024];
    int bytesRead;
    long start = System.currentTimeMillis();
    while ((bytesRead = input.read(buf)) > 0)
    {
        output.write(buf, 0, bytesRead);
    }
    long end = System.currentTimeMillis();

    input.close();
    output.close();

    return (end-start);
}

private static long fileCopyUsingNIOChannelClass(File fileToCopy, File newFile) throws IOException
{
    FileInputStream inputStream = new FileInputStream(fileToCopy);
    FileChannel inChannel = inputStream.getChannel();

    FileOutputStream outputStream = new FileOutputStream(newFile);
    FileChannel outChannel = outputStream.getChannel();

    long start = System.currentTimeMillis();
    inChannel.transferTo(0, fileToCopy.length(), outChannel);
    long end = System.currentTimeMillis();

    inputStream.close();
    outputStream.close();

    return (end-start);
}

private static long fileCopyUsingApacheCommons(File fileToCopy, File newFile) throws IOException
{
    long start = System.currentTimeMillis();
    FileUtils.copyFile(fileToCopy, newFile);
    long end = System.currentTimeMillis();
    return (end-start);
}

private static long fileCopyUsingNIOFilesClass(File fileToCopy, File newFile) throws IOException
{
    Path source = Paths.get(fileToCopy.getPath());
    Path destination = Paths.get(newFile.getPath());
    long start = System.currentTimeMillis();
    Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
    long end = System.currentTimeMillis();

    return (end-start);
}

NIO चैनल वर्ग का उपयोग करते समय मैं जो कुछ भी देख सकता हूं, वह केवल यह है कि मैं अभी भी इंटरमीडिएट फाइल कॉपी प्रगति दिखाने का कोई तरीका नहीं खोज सकता।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.