Java-는지 여부를 확인하는 방법 파일의 이름은 유효한가요?[중복]

StackOverflow https://stackoverflow.com/questions/893977

  •  23-08-2019
  •  | 
  •  

문제

에서 Java 응용 프로그램이 내 이름을 바꾸는 파일을 파일 이름에서 제공하는 문자열을 매개 변수입니다.는 방법이 있습니다

boolean OKtoRename(String oldName, String newName)

기본적으로 검사할지 여부를 newName 지 않는 이미 다른 파일로 내가 원하지 않을 것을 묻어 기존.

그것은 지금이 발생했는데 아마도 새 문자열을 사용하지 않을 나타내는 유효한 파일 이름입니다.그래서 저는 생각을 추가 이를 확인하는 방법:

if (new File(newName).isFile()) { 
    return false; 
}

분명히 맞지 않을 방지하기 때문에 대부분의 경우 newFile 아직 존재하지 않고,따라서 비록 그것이 OKtoRename,함수는 false 를 반환합니다.

궁금,이 있습 방법(저는 알고 있지 않 java.io.파일의 개체)아 canExist()?나 리조트 regex 을 확인하 newFile 문자열을 포함하지 않는 잘못된 문자를(예를들면?, *,",:)?이 있는지 궁금도 함수에서 어딘가에 숨겨진 JDK 는 저에게 말하면 문자열 수 있는 가능성을 나타내는 유효한 파일 이름입니다.

도움이 되었습니까?

해결책

사용 createNewFile(), 파일이 아직 존재하지 않는 경우에만 파일을 원자 적으로 생성합니다.

파일이 생성되면 이름이 유효하며 기존 파일을 막지 않습니다. 그런 다음 파일을 열고 데이터에서 다른 방법으로 효율적으로 복사 할 수 있습니다. FileChannel.transferXXX 운영.

일반적으로 점검과 창조물은 원자력이어야한다는 점을 명심해야합니다. 먼저 작업이 안전한지 확인하면 작업을 별도의 단계로 수행하면 그 동안 조건이 변경되었을 수 있습니다.

생각을위한 추가 음식은이 관련 게시물에서 제공됩니다. "Java에서 작업/복사."


업데이트:

이 답변 이후, Nio.2 API가 도입되어 파일 시스템과 더 많은 상호 작용을 추가했습니다.

대화식 프로그램이 있다고 가정하고 파일이 잠재적으로 유효한지 여부를 각 키 스트로크 후 확인하려고합니다. 예를 들어, "저장"을 누른 후 오류 대화 상자를 팝업하지 않고 항목이 유효한 경우에만 "저장"버튼을 활성화 할 수 있습니다. 위의 제안이 요구하는 많은 불필요한 파일을 삭제하고 삭제하는 것은 엉망인 것처럼 보입니다.

Nio.2를 사용하면 a를 만들 수 없습니다 Path 파일 시스템에 불법 인 문자가 포함 된 인스턴스. an InvalidPathException 당신이 만들려고하자마자 제기됩니다. Path.

그러나 Windows의 "PRN"과 같은 유효한 문자로 구성된 불법 이름을 검증하는 API는 없습니다. 해결 방법으로 실험은 불법 파일 이름을 사용하면 속성에 액세스하려고 할 때 ( Files.getLastModifiedTime(), 예를 들어).

존재하는 파일에 대한 법적 이름을 지정하면 예외는 아닙니다.

존재하지 않는 파일의 법적 이름을 지정하면 발생합니다. NoSuchFileException.

불법 이름을 지정하는 경우 FileSystemException 제기됩니다.

그러나 이것은 매우 Kludgey처럼 보이며 다른 운영 체제에 신뢰할 수 없을 수도 있습니다.

다른 팁

나는 조립의 목록은 불법 파일이름이 문자가(고려 UNIX,Mac OS X,윈도우 시스템)에 따라 일부 온라인 연구의 몇 개월 전에.는 경우 새로운 파일 이름에 포함된 이러한 위험이 있는 유효하지 않을 수 있습니다.

private static final char[] ILLEGAL_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };

편집: 내가 좋아하는 스트레스,이 지 않은 완벽한 솔루션:으로 주석,지적했지만 이 테스트를 통과 당신의 파일 이름을 수 있습 Windows 특정 키워드를 다음과 같 COM,PRN,etc.그러나,당신의 파일 이름에 포함된 이러한 문자,그것은 확실히 문제가 발생에 크로스-플랫폼은 환경입니다.

여기 시스템 특정 방식이 제안됩니다.

public static boolean isFilenameValid(String file) {
  File f = new File(file);
  try {
    f.getCanonicalPath();
    return true;
  } catch (IOException e) {
    return false;
  }
}

일식을 개발하는 경우 확인하십시오 org.eclipse.core.internal.resources.OS

public abstract class OS {
   private static final String INSTALLED_PLATFORM;

   public static final char[] INVALID_RESOURCE_CHARACTERS;
   private static final String[] INVALID_RESOURCE_BASENAMES;
   private static final String[] INVALID_RESOURCE_FULLNAMES;

   static {
      //find out the OS being used
      //setup the invalid names
      INSTALLED_PLATFORM = Platform.getOS();
      if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
         //valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp
         INVALID_RESOURCE_CHARACTERS = new char[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
         INVALID_RESOURCE_BASENAMES = new String[] {"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 
               "com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
               "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
         Arrays.sort(INVALID_RESOURCE_BASENAMES);
         //CLOCK$ may be used if an extension is provided
         INVALID_RESOURCE_FULLNAMES = new String[] {"clock$"}; //$NON-NLS-1$
      } else {
         //only front slash and null char are invalid on UNIXes
         //taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html
         INVALID_RESOURCE_CHARACTERS = new char[] {'/', '\0',};
         INVALID_RESOURCE_BASENAMES = null;
         INVALID_RESOURCE_FULLNAMES = null;
      }
   }

   /**
    * Returns true if the given name is a valid resource name on this operating system,
    * and false otherwise.
    */
   public static boolean isNameValid(String name) {
      //. and .. have special meaning on all platforms
      if (name.equals(".") || name.equals("..")) //$NON-NLS-1$ //$NON-NLS-2$
         return false;
      if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
         //empty names are not valid
         final int length = name.length();
         if (length == 0)
            return false;
         final char lastChar = name.charAt(length-1);
         // filenames ending in dot are not valid
         if (lastChar == '.')
            return false;
         // file names ending with whitespace are truncated (bug 118997)
         if (Character.isWhitespace(lastChar))
            return false;
         int dot = name.indexOf('.');
         //on windows, filename suffixes are not relevant to name validity
         String basename = dot == -1 ? name : name.substring(0, dot);
         if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase()) >= 0)
            return false;
         return Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase()) < 0;
      }
      return true;
   }
}

이것이 내가 이것을 구현 한 방법입니다.

public boolean isValidFileName(final String aFileName) {
    final File aFile = new File(aFileName);
    boolean isValid = true;
    try {
        if (aFile.createNewFile()) {
            aFile.delete();
        }
    } catch (IOException e) {
        isValid = false;
    }
    return isValid;
}

나에게 그것은 OS 의존적 문제 인 것 같습니다. 파일 이름에서 유효하지 않은 문자를 확인할 수 있습니다. Windows는 파일의 이름을 바꾸려고 할 때 파일에 다음 문자가 포함될 수 없다는 메시지가 표시됩니다. / : *? <> | 당신의 질문이 "도서관이 나를 위해 일하는 도서관이 있습니까?"인지 확실하지 않습니다. 이 경우 나는 아무것도 모른다.

Java 7 이후에 내가 찾은 것만 Paths 그것은 이름이라는 방법이 있습니다 get 하나 이상이 필요합니다 StringS와 던지기

InvalidPathException - 경로 문자열을 경로로 변환 할 수없는 경우

사용

String validName = URLEncoder.encode( fileName , "UTF-8");

File newFile = new File( validName );

일을한다.

오늘 방금 찾았습니다. 100% 작동하는지 확실하지 않지만 지금까지 유효한 파일 이름을 만들 수있었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top