জাভাতে ফাইল তালিকাভুক্ত করার সেরা উপায়, তারিখ সংশোধিত অনুসারে সাজানো?


240

আমি একটি ডিরেক্টরিতে ফাইলগুলির একটি তালিকা পেতে চাই, তবে আমি এটি এটিকে সাজিয়ে রাখতে চাই যে প্রাচীনতম ফাইলগুলি প্রথম are আমার সমাধানটি ছিল ফাইল.লিস্টফাইলে কল করা এবং কেবল ফাইল.লাইস্টমোডিফায়েডের উপর ভিত্তি করে তালিকাটি রিসর্ট করা, তবে আমি আরও ভাবছিলাম যে এর থেকে আরও ভাল উপায় আছে কিনা।

সম্পাদনা: আমার বর্তমান সমাধানটি যেমন পরামর্শ করা হয়েছে তেমন কোনও বেনামে তুলক ব্যবহার করা হয়:

File[] files = directory.listFiles();

Arrays.sort(files, new Comparator<File>(){
    public int compare(File f1, File f2)
    {
        return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
    } });

1
এর "নতুন দীর্ঘ" অংশটি কী? কেন আপনি শুধু তাদের সাথে দীর্ঘায়ুদের তুলনা করবেন না? যা আপনাকে তুলনা করার পদ্ধতিটিতে পৌঁছানোর জন্য বহু লম্বা লম্বা সৃষ্টি এড়াতে পারে ...
জন গার্ডনার

এই কোডটি সংকলন করে না। তুলনা পদ্ধতিগুলি প্রত্যাশা করে যে রিটার্নটি লংয়ের পরিবর্তে কোনও int হয়।
মার্কোস্পেরির

1
আমি কি কেবলমাত্র এই সমাধানটিকে উন্মাদ বিবেচনা করি? আপনি file.lastModified()বিশাল পরিমাণে কল করছেন । সমস্ত তারিখ প্রথমে পাওয়া ভাল এবং পরে অর্ডার করুন, যাতে file.lastModified()প্রতি ফাইলটিতে কেবল একবার বলা হয়।
cprcrack

1
আপনি Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
অ্যাপাচি

5
জাভা 8 এর সাথে আরও ভাল সমাধান রয়েছে (ভিনিসিয়াসস এর উত্তর দেখুন):Arrays.sort(files, Comparator.comparingLong(File::lastModified));
স্টারব্রোকড

উত্তর:


99

আমি মনে করি আপনার সমাধানটি একমাত্র বুদ্ধিমান উপায়। ফাইলগুলির তালিকা পাওয়ার একমাত্র উপায় হ'ল ফাইল.লিস্টফাইলস () ব্যবহার করা এবং ডকুমেন্টেশনে বলা হয় যে এটি ফাইলে ফিরে আসা ফাইলগুলির ক্রম সম্পর্কে কোনও গ্যারান্টি দেয় না। অতএব আপনি যদি একটি লিখতে প্রয়োজন comparator যে ব্যবহারসমূহ File.lastModified () এবং এই পাস, ফাইল অ্যারে সহ, Arrays.sort ()


আমি এখানে ফর্ম্যাটিংটি কীভাবে ঠিক করব? পূর্বরূপে দুর্দান্ত দেখায় তবে চতুর্থ লিঙ্কটি স্ক্রুযুক্ত।
ড্যান ডায়ার

1
তুলনা পদ্ধতি লঙ্ঘনের ত্রুটির পরিণতিতে বাছাই করার সময় ফাইল.লাস্টমডিফাইড পরিবর্তিত হতে পারে, দেখুন: সম্ভাব্য উন্নততর সমাধানের জন্য stackoverflow.com/questions/20431031 দেখুন stackoverflow.com/a/4248059/314089
আইসিয়েরেসর

48

আপনার কাছে অনেকগুলি ফাইল থাকলে এটি দ্রুত হতে পারে। এটি সাজসজ্জা-সাজানোর-আনকোয়ার্ট প্যাটার্নটি ব্যবহার করে যাতে প্রতিটি ফাইলের সর্বশেষ-পরিবর্তিত তারিখ প্রতিবারের চেয়ে একবারে সাজানো হয় বাছাই অ্যালগরিদম দুটি ফাইলের তুলনা করে। এটি সম্ভাব্যভাবে ও (এন লগ এন) থেকে ও (এন) এর আই / ও কলগুলির সংখ্যা হ্রাস করে।

এটি আরও কোড, তবে এটি কেবল তখনই ব্যবহার করা উচিত যদি আপনি মূলত গতির সাথে উদ্বিগ্ন হন এবং এটি অনুশীলনে দ্রুত পরিমাপ করা হয় (যা আমি পরীক্ষা করে দেখিনি)।

class Pair implements Comparable {
    public long t;
    public File f;

    public Pair(File file) {
        f = file;
        t = file.lastModified();
    }

    public int compareTo(Object o) {
        long u = ((Pair) o).t;
        return t < u ? -1 : t == u ? 0 : 1;
    }
};

// Obtain the array of (file, timestamp) pairs.
File[] files = directory.listFiles();
Pair[] pairs = new Pair[files.length];
for (int i = 0; i < files.length; i++)
    pairs[i] = new Pair(files[i]);

// Sort them by timestamp.
Arrays.sort(pairs);

// Take the sorted pairs and extract only the file part, discarding the timestamp.
for (int i = 0; i < files.length; i++)
    files[i] = pairs[i].f;

5
সেরা উত্তর, সম্ভবত এটি কেবলমাত্র "তুলনা পদ্ধতি লঙ্ঘন ত্রুটি" প্রতিরোধকারী যদি বাছাইয়ের সময় সর্বশেষ পরিবর্তন হয়?
আইসিয়েরেসর

1
তুলনা পদ্ধতি লঙ্ঘনের কারণে যখন আপনি অবৈধআর্গুমেন্টএক্সপেশন না পাওয়ার বিষয়ে উদ্বিগ্ন হন তখনও এটি ব্যবহার করা উচিত। একই লাস্টমোডাইফাইড মান সহ একাধিক ফাইল থাকলে এই ফাইলগুলি বাদ দিতে পারে ম্যাপ ব্যবহারের পদ্ধতিটি ব্যর্থ হবে। এটি অবশ্যই একটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
অ্যান্ড্রয়েড বিকাশকারী

44

জাভা 8 সাল থেকে মার্জিত সমাধান:

File[] files = directory.listFiles();
Arrays.sort(files, Comparator.comparingLong(File::lastModified));

অথবা, যদি আপনি এটি সাজানো ক্রমে চান তবে কেবল এটির বিপরীত করুন:

File[] files = directory.listFiles();
Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());

2
এটি সত্যই সহজ সমাধান। তালিকার জন্য:files.sort(Comparator.comparingLong(File::lastModified));
স্টারব্রোকড

@ স্টারব্রোকেন আপনার সমাধান যদি ফাইলগুলি [] এর মতো সরল অ্যারে হয় তবে ডিরেক্টরী.লিস্টফাইলেস () দ্বারা ফিরে আসে যদি আপনার সমাধান কাজ করে না।
viniciussss

@ স্টারব্রোকেন আপনার সমাধানের সমাধানের জন্য, একটি ব্যবহার করা দরকার ArrayList<File> files = new ArrayList<File>(Arrays.asList(directory.listFiles())), এটি সহজের চেয়ে সহজ নয় File[] files = directory.listFiles()
ভিনিসিয়াসস

হ্যা আমি আপনার সাথে একমত. আপনার কাছে যদি ফাইলগুলির একটি অ্যারে থাকে তবে একটি তালিকা তৈরি করার কোনও কারণ নেই। (যদি কেউ বিস্মিত হন, তবে ArrayList<File>(...)ভিনিসিয়াসস মন্তব্যে সেই 'অতিরিক্ত' প্রয়োজন এমন একটি মিউটਟੇবল তালিকা পেতে বাছাই করা যায়। সুতরাং আমি সবেমাত্র সেই কোডটি যুক্ত করেছি যাতে লোকেরা তালিকাগুলির পাশাপাশি তালিকাবদ্ধ হয়ে থাকে তবে লোকেরা কেবল এটি অনুলিপি করতে পারে।
স্টারব্রোকড

Comparatorবর্গ কোনো পদ্ধতি কল নেইcomparingLong
zeleven

37

অনুরূপ পদ্ধতির সম্পর্কে কী তবে লং অবজেক্টগুলিতে বক্সিং না করে:

File[] files = directory.listFiles();

Arrays.sort(files, new Comparator<File>() {
    public int compare(File f1, File f2) {
        return Long.compare(f1.lastModified(), f2.lastModified());
    }
});

এটি শুধুমাত্র 19++ এর API বলে মনে হচ্ছে।
গ্যাবার

4
Long.valueOf (f1.lastModified ()) রিটার্ন ব্যবহার করুন। তুলনা করুন (f2.lastModified ()); পরিবর্তে নিম্ন api জন্য।
মার্টিন সিক্স

25

আপনি অ্যাপাচি কমন্স আইও দেখতে পারেন , এটিতে সর্বশেষ পরিবর্তিত তুলনাকারী এবং ফাইলগুলির সাথে কাজ করার জন্য আরও অনেক দুর্দান্ত ইউটিলিটি রয়েছে।


5
এই সমাধানের সাথে জাভাডকে একটি অদ্ভুত ত্রুটি রয়েছে, কারণ জাভাদোক "লাস্টমোডিফাইডফাইকম্পোরেটর ব্যবহার করেছেন ST একটি তালিকা সাজানোর জন্য, কিন্তু LASTMODIFIED_COMPARATOR কে "তুলনামূলক <ফাইল>" হিসাবে ঘোষণা করা হয়েছে, সুতরাং এটি কোনও "বাছাই" পদ্ধতি প্রকাশ করে না।
ত্রিস্তান

4
এটি এর মতো ব্যবহার করুন: লিঙ্ক
ক্লিও

1
তুলনা পদ্ধতি লঙ্ঘনের ত্রুটির পরিণতিতে বাছাই করার সময় ফাইল.লাস্টমডিফাইড পরিবর্তিত হতে পারে, দেখুন: সম্ভাব্য উন্নততর সমাধানের জন্য stackoverflow.com/questions/20431031 দেখুন stackoverflow.com/a/4248059/314089
আইসিয়েরেসর


16

জাভা 8 তে:

Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));


13

আমদানি:

org.apache.commons.io.comparator.LastModifiedFileComparator

অ্যাপাচি কমন্স

কোড:

public static void main(String[] args) throws IOException {
        File directory = new File(".");
        // get just files, not directories
        File[] files = directory.listFiles((FileFilter) FileFileFilter.FILE);

        System.out.println("Default order");
        displayFiles(files);

        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
        System.out.println("\nLast Modified Ascending Order (LASTMODIFIED_COMPARATOR)");
        displayFiles(files);

        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
        System.out.println("\nLast Modified Descending Order (LASTMODIFIED_REVERSE)");
        displayFiles(files);

    }

লাস্টমোডিফায়েডফিলিক্যাম্পেরেটরটি কোথা থেকে তা তাত্ক্ষণিকভাবে পরিষ্কার নয় LA হতে পারে অ্যাপাচি কমন্সে লিঙ্ক যুক্ত করা আইও সাহায্য করবে।
ব্রডব্যান্ড

সম্পন্ন, ধন্যবাদ ব্রডব্যান্ড
বালাজী বোগগ্রাম রমনারায়ণ

10

আপনি বাছাই করা ফাইলগুলি যদি একই সময়ে বাছাই করা হচ্ছে সংশোধন বা আপডেট করা যায়:


জাভা 8+

private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
    try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
        return fileStream
            .map(Path::toFile)
            .collect(Collectors.toMap(Function.identity(), File::lastModified))
            .entrySet()
            .stream()
            .sorted(Map.Entry.comparingByValue())
//            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))  // replace the previous line with this line if you would prefer files listed newest first
            .map(Map.Entry::getKey)
            .map(File::toPath)  // remove this line if you would rather work with a List<File> instead of List<Path>
            .collect(Collectors.toList());
    }
}

জাভা 7

private static List<File> listFilesOldestFirst(final String directoryPath) throws IOException {
    final List<File> files = Arrays.asList(new File(directoryPath).listFiles());
    final Map<File, Long> constantLastModifiedTimes = new HashMap<File,Long>();
    for (final File f : files) {
        constantLastModifiedTimes.put(f, f.lastModified());
    }
    Collections.sort(files, new Comparator<File>() {
        @Override
        public int compare(final File f1, final File f2) {
            return constantLastModifiedTimes.get(f1).compareTo(constantLastModifiedTimes.get(f2));
        }
    });
    return files;
}


এই উভয় সমাধানই ডিরেক্টরিতে প্রতিটি ফাইলের জন্য অবিচ্ছিন্ন শেষ বারের সময়টিকে বাঁচাতে অস্থায়ী মানচিত্রের ডেটা কাঠামো তৈরি করে। আমাদের এটি করার দরকার কারণ হ'ল যদি আপনার ফাইলগুলি আপডেট করা বা সংশোধন করা হচ্ছে যখন আপনার সাজানোর কাজটি করা হচ্ছে তবে আপনার তুলনাকারী তুলনাকারী ইন্টারফেসের সাধারণ চুক্তির ট্রান্সজিটিটি প্রয়োজনীয়তা লঙ্ঘন করবে কারণ তুলনা চলাকালীন শেষ পরিবর্তনকৃত সময়গুলি পরিবর্তন হতে পারে।

অন্যদিকে, আপনি যদি জানেন যে ফাইলগুলি আপনার সাজানোর সময় আপডেট করা বা সংশোধন করা হবে না, আপনি এই প্রশ্নের কাছে জমা দেওয়া অন্য কোনও উত্তর দিয়ে চলে যেতে পারেন, যার মধ্যে আমি আংশিক:

জাভা 8+ (সাজানোর সময় একযোগে কোনও পরিবর্তন নেই)

private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
    try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
        return fileStream
            .map(Path::toFile)
            .sorted(Comparator.comparing(File::lastModified))
            .map(File::toPath)  // remove this line if you would rather work with a List<File> instead of List<Path>
            .collect(Collectors.toList());
    }
}

দ্রষ্টব্য: আমি জানি যে আপনি বাছাই করা স্ট্রিম অপারেশনে ফাইল :: getLastModifiedTime এপিআই ব্যবহার করে উপরের উদাহরণে ফাইল অবজেক্টগুলিতে এবং থেকে অনুবাদ এড়াতে পারবেন , তবে, আপনার ল্যাম্বদার ভিতরে যাচাই করা আইও ব্যতিক্রমগুলি যা আপনাকে সর্বদা ব্যথার সাথে মোকাবিলা করতে হবে । আমি বলব পারফরম্যান্স যদি পর্যাপ্ত সমালোচনামূলক হয় যে অনুবাদটি গ্রহণযোগ্য নয় তবে আমি লাম্বডায় চেক করা আইওএক্সেপশনটিকে একটি চেক না করা আইওএক্সেপশন হিসাবে প্রচার করে বা ফাইল এপি সম্পূর্ণভাবে ফোরোগোস করে কেবল ফাইল অবজেক্টের সাথে ডিল করব:

final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));

2
public String[] getDirectoryList(String path) {
    String[] dirListing = null;
    File dir = new File(path);
    dirListing = dir.list();

    Arrays.sort(dirListing, 0, dirListing.length);
    return dirListing;
}

1
এটি প্রকৃতপক্ষে প্রশ্নের মধ্যে উল্লিখিত তারিখের সংশোধিত সম্পত্তি অনুসারে বাছাই করে না। বাছাইয়ের ফাংশনটি ফাইল অবজেক্টের প্রাকৃতিক ক্রম ব্যবহার করবে যা পাথ নামের সিস্টেম-নির্ভর লিক্সোগ্রাফিক
ম্যাট চ্যান 21

2
Collections.sort(listFiles, new Comparator<File>() {
        public int compare(File f1, File f2) {
            return Long.compare(f1.lastModified(), f2.lastModified());
        }
    });

listFilesঅ্যারেলিস্টে সমস্ত ফাইলের সংগ্রহ কোথায়



1

আপনি অ্যাপাচি লাস্টমোডিফায়েডফিলকমারেটর লাইব্রেরি ব্যবহার করতে পারেন

 import org.apache.commons.io.comparator.LastModifiedFileComparator;  


File[] files = directory.listFiles();
        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
        for (File file : files) {
            Date lastMod = new Date(file.lastModified());
            System.out.println("File: " + file.getName() + ", Date: " + lastMod + "");
        }

1
private static List<File> sortByLastModified(String dirPath) {
    List<File> files = listFilesRec(dirPath);
    Collections.sort(files, new Comparator<File>() {
        public int compare(File o1, File o2) {
            return Long.compare(o1.lastModified(), o2.lastModified());
        }
    });
    return files;
}

0

আমি এই পোস্টে এসেছি যখন আমি একই ইস্যুটি খুঁজছিলাম কিন্তু ভিতরে ছিলাম android । আমি বলি না এটি সর্বশেষ পরিবর্তিত তারিখ অনুসারে ফাইল বাছাই করার সর্বোত্তম উপায়, তবে এটি এখনও খুঁজে পাওয়া সবচেয়ে সহজতম উপায়।

নীচের কোডটি কারও পক্ষে সহায়ক হতে পারে-

File downloadDir = new File("mypath");    
File[] list = downloadDir.listFiles();
    for (int i = list.length-1; i >=0 ; i--) {
        //use list.getName to get the name of the file
    }

ধন্যবাদ


কিন্তু কে বাছাই করে?
ড্যাব

forলুপের আরম্ভের অংশে আপনি দেখতে পাচ্ছেন যে আমি নিয়ে list.length-1গিয়েছি i >=0যা কেবল আপনাকে বিপরীত ক্রমে পুনরাবৃত্তি করে।
হিরदेश বিশ্বদেব

0

কোনও অতিরিক্ত তুলনামূলক ছাড়াই সমস্যাটি পরিচালনা করার খুব সহজ এবং সুবিধাজনক উপায় রয়েছে। স্ট্রিংয়ে ফাইলের নাম দিয়ে কেবল পরিবর্তিত তারিখটি কোড করুন, এটি বাছাই করুন এবং পরে এটি আবার সরিয়ে দিন।

স্থির দৈর্ঘ্যের 20 টির স্ট্রিং ব্যবহার করুন, এতে পরিবর্তিত তারিখটি (দীর্ঘ) দিন এবং শীর্ষস্থানীয় শূন্যগুলি পূরণ করুন। তারপরে এই স্ট্রিংটিতে কেবল ফাইলের নাম যুক্ত করুন:

String modified_20_digits = ("00000000000000000000".concat(Long.toString(temp.lastModified()))).substring(Long.toString(temp.lastModified()).length()); 

result_filenames.add(modified_20_digits+temp.getAbsoluteFile().toString());

যা হয় তা এখানে:

ফাইলের নাম 1: সি: \ ডেটা \ ফাইল1 এইচটিএমএল সর্বশেষ সংশোধিত: 1532914451455 সর্বশেষ পরিবর্তিত 20 টি সংখ্যা: 00000001532914451455

ফাইলের নাম 1: সি: \ ডেটা \ ফাইল 2 এইচটিএমএল সর্বশেষ সংশোধিত: 1532918086822 সর্বশেষ পরিবর্তিত 20 টি সংখ্যা: 00000001532918086822

ফিল্মের নামগুলি এতে রূপান্তর করে:

ফাইলের নাম 1: 00000001532914451455C: \ ডেটা \ file1.html

ফাইলের নাম 2: 00000001532918086822C: \ ডেটা \ file2.html

তারপরে আপনি কেবল এই তালিকাটি বাছাই করতে পারেন।

আপনাকে যা করতে হবে তা হ'ল পরে আবার 20 টি অক্ষর ফেলা (জাভা 8 এ, আপনি এটি .replaceAl ফাংশনটি ব্যবহার করে কেবল একটি লাইন দিয়ে পুরো অ্যারের জন্য স্ট্রিপ করতে পারেন)


-1

এছাড়াও একটি সম্পূর্ণ আলাদা উপায় রয়েছে যা আরও সহজ হতে পারে, কারণ আমরা বিপুল সংখ্যার সাথে ডিল করি না।

আপনি সমস্ত ফাইলের নাম এবং শেষমোডিফিকেশন তারিখগুলি পুনরুদ্ধার করার পরে পুরো অ্যারে বাছাই করার পরিবর্তে, আপনি কেবলমাত্র প্রতিটি ফাইল নাম তালিকার ডান অবস্থানে পুনরুদ্ধার করার পরে সন্নিবেশ করতে পারেন।

আপনি এটি এর মতো করতে পারেন:

list.add(1, object1)
list.add(2, object3)
list.add(2, object2)

আপনি অবজেক্ট 2 পজিশনে 2 যুক্ত করার পরে এটি অবজেক্ট 3 পজিশনে স্থানান্তরিত হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.