20

フォルダー内に一連のファイルがあり、1 つを除いてすべて似たような名前で始まります。次に例を示します。

Coordinate.txt
Spectrum_1.txt
Spectrum_2.txt
Spectrum_3.txt
.
.
.
Spectrum_11235

指定したフォルダからすべてのファイルを一覧表示できますが、一覧がスペクトル番号の昇順になっていません。例: プログラムを実行すると、次の結果が得られます。

Spectrum_999.txt
Spectrum_9990.txt
Spectrum_9991.txt
Spectrum_9992.txt
Spectrum_9993.txt
Spectrum_9994.txt
Spectrum_9995.txt
Spectrum_9996.txt
Spectrum_9997.txt
Spectrum_9998.txt
Spectrum_9999.txt

しかし、この順序は正しくありません。Spectrum_999.txt の後に Spectrum_1000.txt ファイルがあるはずです。誰でも助けることができますか?コードは次のとおりです。

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

    public class FileInput {

        public void userInput()
        {
            Scanner scanner = new Scanner( System.in );
            System.out.println("Enter the file path: ");
            String dirPath = scanner.nextLine(); // Takes the directory path as the user input

            File folder = new File(dirPath);
            if(folder.isDirectory())
            {
                File[] fileList = folder.listFiles();

                Arrays.sort(fileList);

                System.out.println("\nTotal number of items present in the directory: " + fileList.length );


                // Lists only files since we have applied file filter
                for(File file:fileList)
                {
                    System.out.println(file.getName());
                }

                // Creating a filter to return only files.
                FileFilter fileFilter = new FileFilter()
                {
                    @Override
                    public boolean accept(File file) {
                        return !file.isDirectory();
                    }
                };

                fileList = folder.listFiles(fileFilter);

                // Sort files by name
                Arrays.sort(fileList, new Comparator()
                {
                    @Override
                    public int compare(Object f1, Object f2) {
                        return ((File) f1).getName().compareTo(((File) f2).getName());
                    }
                });

                //Prints the files in file name ascending order
                for(File file:fileList)
                {
                    System.out.println(file.getName());
                }

            }   
        }
    }
4

11 に答える 11

3

上記のコメントで問題の解決策を見つけることができますが、リンクのみが公開されていることを考慮して、そのサイトからコードを提供しています。うまくいきました。

  1. 独自の AlphanumericalComparator を作成する必要があります。

     import java.io.File;
     import java.util.Comparator;
    
    public class AlphanumFileComparator implements Comparator
    {
    
       private final boolean isDigit(char ch)
       {
        return ch >= 48 && ch <= 57;
       }
    
    
    private final String getChunk(String s, int slength, int marker)
    {
        StringBuilder chunk = new StringBuilder();
        char c = s.charAt(marker);
        chunk.append(c);
        marker++;
        if (isDigit(c))
        {
            while (marker < slength)
            {
                c = s.charAt(marker);
                if (!isDigit(c))
                    break;
                chunk.append(c);
                marker++;
            }
        } else
        {
            while (marker < slength)
            {
                c = s.charAt(marker);
                if (isDigit(c))
                    break;
                chunk.append(c);
                marker++;
            }
        }
        return chunk.toString();
    }
    
    public int compare(Object o1, Object o2)
    {
        if (!(o1 instanceof File) || !(o2 instanceof File))
        {
            return 0;
        }
        File f1 = (File)o1;
        File f2 = (File)o2;
        String s1 = f1.getName();
        String s2 = f2.getName();
    
        int thisMarker = 0;
        int thatMarker = 0;
        int s1Length = s1.length();
        int s2Length = s2.length();
    
        while (thisMarker < s1Length && thatMarker < s2Length)
        {
            String thisChunk = getChunk(s1, s1Length, thisMarker);
            thisMarker += thisChunk.length();
    
            String thatChunk = getChunk(s2, s2Length, thatMarker);
            thatMarker += thatChunk.length();
    
            /** If both chunks contain numeric characters, sort them numerically **/
    
            int result = 0;
            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
            {
                // Simple chunk comparison by length.
                int thisChunkLength = thisChunk.length();
                result = thisChunkLength - thatChunk.length();
                // If equal, the first different number counts
                if (result == 0)
                {
                    for (int i = 0; i < thisChunkLength; i++)
                    {
                        result = thisChunk.charAt(i) - thatChunk.charAt(i);
                        if (result != 0)
                        {
                            return result;
                        }
                    }
                }
            } else
            {
                result = thisChunk.compareTo(thatChunk);
            }
    
            if (result != 0)
                return result;
        }
    
        return s1Length - s2Length;
    }
    }
    

2. このクラスに応じて、ファイルを並べ替えます。

     File[] listOfFiles = rootFolder.listFiles();
     Arrays.sort(listOfFiles, new AlphanumFileComparator() );
     ...to sth with your files.

それが役に立てば幸い。それは魅力のように私にとってはうまくいきました。

ソリューション: http://www.davekoelle.com/files/AlphanumComparator.java こちら

于 2016-05-29T12:34:18.687 に答える
2
Arrays.sort(fileList, new Comparator()
{
    @Override
    public int compare(Object f1, Object f2) {
        String fileName1 = ((File) f1).getName();
        String fileName2 = ((File) f1).getName();

        int fileId1 = Integer.parseInt(fileName1.split("_")[1]);
        int fileId2 = Integer.parseInt(fileName2.split("_")[1]);

        return fileId1 - fileId2;
    }
});

名前に_が含まれていないファイルを必ず処理してください

于 2013-06-03T14:15:30.620 に答える
1

Ivan Gerasimiv によるスマート AlphaDecimal 比較器の最適な実装は、こちらで見つかりました。これは、標準の JDK Comparators の拡張としてここで提案され、ここスレッドで議論されました。
残念ながら、この変更はまだ JDK に反映されていません (私の知る限り)。ただし、最初のリンクのコードを解決策として使用できます。私にとって、それは魅力のように機能しました。

于 2020-11-24T18:57:59.463 に答える
0

これを実現する最も簡単な方法は、 NameFileComparator.NAME_COMPARATORを使用することです。コード形式は次のとおりです。

File[] fileNamesArr = filePath.listFiles();
if(fileNamesArr != null && fileNamesArr.length > 0) {
    Arrays.sort(fileNamesArr, NameFileComparator.NAME_COMPARATOR);
}

NameFileComparatorを実装するには、次の Maven ライブラリを追加する必要があります。

実装 'commons-io:commons-io:2.6'

またインポート:

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

それで全部です...

于 2021-12-09T13:17:27.237 に答える
-1

それを行う別の方法ですが、java8 の機能を使用します

List<Path> x = Files.list(Paths.get("C:\\myPath\\Tools"))
            .filter(p -> Files.exists(p))
            .map(s -> s.getFileName())
            .sorted()
            .collect(Collectors.toList());

x.forEach(System.out::println);
于 2017-07-04T08:29:28.547 に答える
-2

Collections.sort(fileList); arraylist の並べ替えに使用できます。

次に使用します

 for(File file:fileList)                
         System.out.println(file.getName());

Collections.sort()

于 2013-06-03T13:35:19.150 に答える