Programing

Java에서 고유하고 짧은 파일 이름을 생성하는 가장 좋은 방법은 무엇입니까?

lottogame 2020. 11. 1. 17:11
반응형

Java에서 고유하고 짧은 파일 이름을 생성하는 가장 좋은 방법은 무엇입니까?


UUID는 상당히 길기 때문에 반드시 사용하고 싶지는 않습니다.

파일은 디렉토리 내에서 고유해야합니다.

떠오르는 한 가지 생각은를 사용하는 File.createTempFile(String prefix, String suffix)것이지만 파일이 임시 파일이 아니기 때문에 잘못된 것 같습니다.

동일한 밀리 초에 생성 된 두 파일의 경우를 처리해야합니다.


글쎄, 당신은 3 인수 버전을 사용할 수있다 : File.createTempFile(String prefix, String suffix, File directory)당신이 원하는 곳에 놓을 수있게 해줄 것이다. 지시하지 않는 한 Java는 다른 파일과 다르게 처리하지 않습니다. 유일한 단점은 파일 이름의 길이가 8 자 이상이라는 것입니다 (접두사에 최소 3 자, 함수에 의해 생성 된 5 자 이상).

너무 길면 파일 이름 "a"로 시작하여 아직 존재하지 않는 파일을 찾을 때까지 "b", "c"등을 반복 할 수 있다고 가정합니다.


Apache Commons Lang 라이브러리 (http://commons.apache.org/lang ).

org.apache.commons.lang.RandomStringUtils주어진 길이의 임의의 문자열을 생성하는 데 사용할 수 있는 클래스 가 있습니다. 파일 이름 생성뿐만 아니라 매우 편리합니다!

다음은 그 예입니다.

String ext = "dat";
File dir = new File("/home/pregzt");
String name = String.format("%s.%s", RandomStringUtils.randomAlphanumeric(8), ext);
File file = new File(dir, name);

타임 스탬프를 사용합니다.

new File( simpleDateFormat.format( new Date() ) );

그리고 simpleDateFormat을 다음과 같이 초기화하십시오.

new SimpleDateFormat("File-ddMMyy-hhmmss.SSS.txt");

편집하다

는 어때

new File(String.format("%s.%s", sdf.format( new Date() ),
                                random.nextInt(9)));

같은 시간에 생성되는 파일 수가 너무 많지 않은 경우.

그게 사실이고 이름이 중요하지 않다면

 new File( "file."+count++ );

:피


이것은 나를 위해 작동합니다.

String generateUniqueFileName() {
    String filename = "";
    long millis = System.currentTimeMillis();
    String datetime = new Date().toGMTString();
    datetime = datetime.replace(" ", "");
    datetime = datetime.replace(":", "");
    String rndchars = RandomStringUtils.randomAlphanumeric(16);
    filename = rndchars + "_" + datetime + "_" + millis;
    return filename;
}

// USE:

String newFile;
do{
newFile=generateUniqueFileName() + "." + FileExt;
}
while(new File(basePath+newFile).exists());

출력 파일 이름은 다음과 같아야합니다.

2OoBwH8OwYGKW2QE_4Sep2013061732GMT_1378275452253.Ext

상기 봐 파일 javadoc에서는 , 메소드 때 createNewFile이 존재하지 않는 경우에만 파일을 생성하며, 파일이 생성 된 경우라고 할 수있는 부울을 반환합니다.

exist () 메서드를 사용할 수도 있습니다.

int i = 0;
String filename = Integer.toString(i);
File f = new File(filename);
while (f.exists()) {
    i++;
    filename = Integer.toString(i);
    f = new File(filename);
}
f.createNewFile();
System.out.println("File in use: " + f);

데이터베이스에 대한 액세스 권한이있는 경우 파일 이름에 시퀀스를 만들고 사용할 수 있습니다.

select mySequence.nextval from dual;

고유성이 보장되며 너무 커지지 않아야합니다 (많은 파일을 펌핑하지 않는 한).


타임 스탬프를 기반으로하는 것을 사용하는 것은 어떨까요 ..?


다른 답변을 결합하여 임의의 값이 추가 된 ms 타임 스탬프를 사용하지 않는 이유는 무엇입니까? 충돌이 없을 때까지 반복하십시오. 실제로는 거의 발생하지 않습니다.

예 : File-ccyymmdd-hhmmss-mmm-rrrrrr.txt


    //Generating Unique File Name
    public String getFileName() {
        String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
        return "PNG_" + timeStamp + "_.png";
    }

문제는 동기화입니다. 분쟁 지역을 분리하십시오.

파일 이름을 다음과 같이 지정합니다. (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
예 :aws1_t1_1447402821007.png


가장 가까운 밀리 초로 반올림 된 타임 스탬프 또는 필요한 정확도를 기반으로 생성하는 것은 어떻습니까? 그런 다음 잠금을 사용하여 함수에 대한 액세스를 동기화하십시오.

마지막으로 생성 된 파일 이름을 저장하는 경우 고유하게 만들기 위해 필요에 따라 연속 문자 또는 추가 숫자를 추가 할 수 있습니다.

또는 잠금없이 수행하려면 시간 단계와 스레드 ID를 사용하고 함수가 1 밀리 초 이상 걸리는지 확인하거나 그렇게 기다리십시오.


고유 한 파일 이름을 만들기위한 몇 가지 솔루션이있는 것 같으므로 해당 파일은 그대로 두겠습니다. 이 방법으로 파일 이름을 테스트합니다.

    String filePath;
    boolean fileNotFound = true;
    while (fileNotFound) {
        String testPath = generateFilename();

        try {
            RandomAccessFile f = new RandomAccessFile(
                new File(testPath), "r");
        } catch (Exception e) {
            // exception thrown by RandomAccessFile if 
            // testPath doesn't exist (ie: it can't be read)

            filePath = testPath;
            fileNotFound = false;
        }
    }
    //now create your file with filePath

이것은 또한 작동합니다

String logFileName = new SimpleDateFormat("yyyyMMddHHmm'.txt'").format(new Date());

logFileName = "loggerFile_" + logFileName;

이 질문에 답하기에는 너무 늦었 음을 이해합니다. 하지만 다른 솔루션과 다른 것 같아서 넣어야한다고 생각합니다.

We can concatenate threadname and current timeStamp as file name. But with this there is one issue like some thread name contains special character like "\" which can create problem in creating file name. So we can remove special charater from thread name and then concatenate thread name and time stamp

fileName = threadName(after removing special charater) + currentTimeStamp

Why not use synchronized to process multi thread. here is my solution,It's can generate a short file name , and it's unique.

private static synchronized String generateFileName(){
    String name = make(index);
    index ++;
    return name;
}
private static String make(int index) {
    if(index == 0) return "";
    return String.valueOf(chars[index % chars.length]) + make(index / chars.length);
}
private static int index = 1;
private static char[] chars = {'a','b','c','d','e','f','g',
        'h','i','j','k','l','m','n',
        'o','p','q','r','s','t',
        'u','v','w','x','y','z'};

blew is main function for test , It's work.

public static void main(String[] args) {
    List<String> names = new ArrayList<>();
    List<Thread> threads = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    String name = generateFileName();
                    names.add(name);
                }
            }
        });
        thread.run();
        threads.add(thread);
    }

    for (int i = 0; i < 10; i++) {
        try {
            threads.get(i).join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    System.out.println(names);
    System.out.println(names.size());

}

참고URL : https://stackoverflow.com/questions/825678/what-is-the-best-way-to-generate-a-unique-and-short-file-name-in-java

반응형