[java] Java로 임시 디렉토리 / 폴더를 작성하는 방법은 무엇입니까?

Java 애플리케이션 내에 임시 디렉토리를 작성하는 표준적이고 안정적인 방법이 있습니까? 거기에 자바의 문제 데이터베이스의 항목 코멘트 코드의 비트를 가지고,하지만 난 보통 라이브러리 (아파치 코 몬즈 등) 중 하나에서 찾을 수있는 표준 용액이 있는지 궁금해?



답변

JDK 7을 사용하는 경우 새 Files.createTempDirectory 클래스를 사용하여 임시 디렉토리를 작성하십시오.

Path tempDirWithPrefix = Files.createTempDirectory(prefix);

JDK 7 이전에는 이렇게해야합니다.

public static File createTempDirectory()
    throws IOException
{
    final File temp;

    temp = File.createTempFile("temp", Long.toString(System.nanoTime()));

    if(!(temp.delete()))
    {
        throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
    }

    if(!(temp.mkdir()))
    {
        throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
    }

    return (temp);
}

원하는 경우 더 나은 예외 (하위 클래스 IOException)를 만들 수 있습니다.


답변

Google Guava 라이브러리에는 유용한 유틸리티가 많이 있습니다. 여기서 주목할 것은 파일 클래스 입니다. 다음과 같은 유용한 방법이 있습니다.

File myTempDir = Files.createTempDir();

이것은 정확히 한 줄로 요청한 것을 수행합니다. 여기 에서 설명서를 읽으면 제안 된 적응이 File.createTempFile("install", "dir")일반적으로 보안 취약점을 유발한다는 것을 알 수 있습니다 .


답변

테스트를 위해 임시 디렉토리가 필요하고 jUnit을 사용중인 경우 문제점 @RuleTemporaryFolder해결하십시오.

@Rule
public TemporaryFolder folder = new TemporaryFolder();

로부터 문서 :

TemporaryFolder 규칙을 사용하면 테스트 방법이 완료 될 때 (통과 여부에 관계없이) 파일 및 폴더를 삭제할 수 있습니다.


최신 정보:

JUnit Jupiter (버전 5.1.1 이상)를 사용하는 경우 JUnit 5 Extension Pack 인 JUnit Pioneer를 사용할 수 있습니다.

프로젝트 문서 에서 복사 :

예를 들어, 다음 테스트는 단일 테스트 메소드에 대한 확장자를 등록하고 파일을 작성하여 임시 디렉토리에 쓰고 내용을 확인합니다.

@Test
@ExtendWith(TempDirectory.class)
void test(@TempDir Path tempDir) {
    Path file = tempDir.resolve("test.txt");
    writeFile(file);
    assertExpectedFileContent(file);
}

JavaDocTempDirectoryJavaDoc 에 대한 추가 정보

그레들 :

dependencies {
    testImplementation 'org.junit-pioneer:junit-pioneer:0.1.2'
}

메이븐 :

<dependency>
   <groupId>org.junit-pioneer</groupId>
   <artifactId>junit-pioneer</artifactId>
   <version>0.1.2</version>
   <scope>test</scope>
</dependency>

업데이트 2 :

@TempDir의 주석 실험적인 기능으로 JUnit을 목성 5.4.0 릴리스에 추가되었습니다. JUnit 5 사용 설명서 에서 복사 한 예 :

@Test
void writeItemsToFile(@TempDir Path tempDir) throws IOException {
    Path file = tempDir.resolve("test.txt");

    new ListWriter(file).write("a", "b", "c");

    assertEquals(singletonList("a,b,c"), Files.readAllLines(file));
}


답변

이 문제를 해결하기 위해 순진하게 작성된 코드는 여기에 몇 가지 답변을 포함하여 경쟁 조건이 있습니다. 역사적으로 경쟁 조건에 대해 신중하게 생각하고 직접 작성하거나 Spina의 답변이 제안한 Google Guava와 같은 타사 라이브러리를 사용하거나 버그가있는 코드를 작성할 수 있습니다.

그러나 JDK 7부터는 좋은 소식이 있습니다! Java 표준 라이브러리 자체는 이제이 문제에 대해 올바르게 작동하는 (비 레이스가 아닌) 솔루션을 제공합니다. 당신이 원하는 java.nio.file.Files # createTempDirectory ()을 . 로부터 문서 :

public static Path createTempDirectory(Path dir,
                       String prefix,
                       FileAttribute<?>... attrs)
                                throws IOException

지정된 접두사를 사용하여 지정된 디렉토리에 새 디렉토리를 작성하여 이름을 생성합니다. 결과 경로는 주어진 디렉토리와 동일한 파일 시스템과 연관됩니다.

디렉토리 이름의 구성 방법에 대한 세부 사항은 구현에 따라 다르므로 지정되지 않았습니다. 가능한 경우 접두사가 후보 이름을 구성하는 데 사용됩니다.

이를 통해 Sun 버그 추적기에서 매우 오래된 버그 보고서 를 효과적으로 해결하여 그러한 기능을 요구했습니다.


답변

이것은 Guava 라이브러리의 Files.createTempDir ()에 대한 소스 코드입니다. 생각만큼 복잡하지 않습니다.

public static File createTempDir() {
  File baseDir = new File(System.getProperty("java.io.tmpdir"));
  String baseName = System.currentTimeMillis() + "-";

  for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
    File tempDir = new File(baseDir, baseName + counter);
    if (tempDir.mkdir()) {
      return tempDir;
    }
  }
  throw new IllegalStateException("Failed to create directory within "
      + TEMP_DIR_ATTEMPTS + " attempts (tried "
      + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
}

기본적으로:

private static final int TEMP_DIR_ATTEMPTS = 10000;

여기를 봐


답변

deleteOnExit()나중에 명시 적으로 삭제하더라도 사용하지 마십시오 .

더 많은 정보를 얻으 려면 Google ‘deleteonexit is evil’ 이지만 문제의 요지는 다음과 같습니다.

  1. deleteOnExit() 일반적인 JVM 종료에 대해서만 삭제하며 JVM 프로세스가 중단되거나 종료되지 않습니다.

  2. deleteOnExit() JVM 종료시에만 삭제-장기 실행 서버 프로세스에는 적합하지 않습니다.

  3. 가장 악한 것- deleteOnExit()각 임시 파일 항목에 대한 메모리를 사용합니다. 프로세스가 몇 달 동안 실행되거나 짧은 시간에 많은 임시 파일을 작성하는 경우 메모리가 소비되고 JVM이 종료 될 때까지 해제하지 마십시오.


답변

자바 1.7로 createTempDirectory(prefix, attrs)createTempDirectory(dir, prefix, attrs)에 포함되어 있습니다java.nio.file.Files

예:
File tempDir = Files.createTempDirectory("foobar").toFile();