Android 파일 이름 바꾸기 File.renameTo() 및 복제본 이름 정의 방법(사용자 정의 규칙)

프로젝트 요구 사항
파일 관리와 관련된 프로젝트를 하려면 한 개 또는 여러 개의 파일 이름을 바꾸어야 하기 때문에 이름이 중복될 수 있다.복사할 때 붙여넣은 곳에 같은 이름 파일이 존재하면 이름을 바꿔야 합니다.
비슷한 사상:
컴퓨터에서 같은 파일 (폴더) 을 복사해서 같은 경로 아래로 붙일 때, 시스템이 자동으로 새 복사본 (Copy) 이름을 생성하는 것을 도와준다는 것을 우리는 알고 있다
나.png MAC은 파일 이름 + "+ 숫자 증가 + 접미사 (나 1.png) Windows는 파일 이름 +"- 복사본 "+"("+ 숫자 증가 +") + 접미사 (나 - 복사본 (2) 입니다.png)
컴퓨터에서 이름을 바꿀 때 이 경로 아래에 이 이름 파일이 있으면 사용자가 이름을 바꿀 수 없다는 것을 알립니다.
지식점
이 절에서 설명할 내용은 다음과 같다.파일 고유의 방법으로 로컬 파일 이름을 바꾸는 방법 2.새 복사본 이름이 필요할 때 사용자 정의 규칙으로 이름을 바꾸는 방법
코드 분석
필요에 따라 인터페이스 이름을 정의할 수 있습니다public boolean rename(FileInfo fileInfo, String newName);.
여기서 FileInfo는 fileName(파일 이름), filePath(파일 경로), isDir(디렉터리 여부) 등의 정보를 포함하는 사용자 정의 데이터 구조입니다.매개 변수 newName 은 새 파일 이름입니다 (접미사 포함)
    /** *  @Description           *  @param fileInfo        *  @param newName    (   ) *  @param admitCopyName       ,         (          ,      ;              ) *  @return        */
    public boolean rename(FileInfo fileInfo, String newName, boolean admitCopyName) {
        //1.      
        if (fileInfo == null || newName == null) {
            Log.e(LOG_TAG, "Rename: null parameter");
            return false;
        }
        //2.        
        String oldPath = fileInfo.getFilePath();
        Log.d(LOG_TAG, "Rename---original path = " + oldPath));
        //3-1.        
        String rootPath = Util.getPathFromFilepath(oldPath); //Util.getPathFromFilepath(String)-     :        (           )
        //3-2.      
        String newPath = Util.makePath(rootPath, newName); //Util.makePath(String, String)-     :                 
        Log.d(LOG_TAG, "Rename---new Path = " + newPath);
        //4.         
        if (oldPath.endsWith(newPath)) { //       ,     
            return true;
        }

        try {
            //5.       File    
            File newFile = new File(newPath);
            //6.               (     )
            if (newFile.exists() && !admitCopyName) { //              
                return false; //     
            }
            //7.              
            while (newFile.exists()) {
                Log.w(LOG_TAG, "Rename---             ---" + newPath);
                //         --Util.getCopyNameFromOriginal(String)-     :              
                newPath = Util.getCopyNameFromOriginal(newPath);
                newFile = new File(newPath);
                Log.i(LOG_TAG, "Rename---new copy Path = " + newPath);
            }
            //8.     File    
            File file = new File(oldPath);
            //9.          
            boolean ret = file.renameTo(newFile);
            Log.i(LOG_TAG, "Rename---    ? " + ((ret) ? "yes!" : "no!"));
            if (ret) {
                //FIXME:             ,      ,      !
                fileInfo.setFileName(Util.getNameFromFilepath(newPath)); //     
                fileInfo.setmFilePath(newPath); //     
             }
            return ret;
        } catch (SecurityException e) {
            Log.e(LOG_TAG, "Fail to rename file," + e.toString());
        }
        return false;
    }

단계별로 해설하다.
중심 내용
코드량이 좀 길어 보이는데 사실 중심은 한마디예요. 9단계에서file.renameTo(newFile);이것은 File을 호출하는 고유한 이름 바꾸기 방법입니다. 그 용도는 다음과 같습니다.
//oldPath like "mnt/sda/sda1/ .png"
File file = new File(oldPath); 
//newPath like "mnt/sda/sda1/    .png"
file.renameTo(new File(newPath));

주의해야 할 점:
첫째, Android SD 카드의 파일 이름이 바뀐 경우 사용 권한을 추가해야 합니다.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

둘째, oldPath와 newPath는 신구 파일의 절대 경로가 되어야 한다.
셋째, newPath에 파일이 존재하고 처리를 하지 않으면, 이 방법을 사용하면 존재하는 파일을 덮어씁니다.
예를 들어 나는'mnt/sda/sda1/'경로 아래에 두 장의 사진이 있는데 하나는'나'라고 부른다.내 사진png", 이럴 때 나는 file.renameTo(new File(newPath));로"나를.png "의 이름이"내 사진 "으로 변경되었습니다.png", 그럼 원래 있던"내 사진."png"은 이름이 바뀐 후에"난."png 덮어쓰기.
주: 세 번째는 제가 실천한 후에 정리한 것이지만 많은 검증을 하지 않았습니다. 잘못된 점이 있으면 가르쳐 주십시오.
넷째, 인터넷에서 일부 사람들이 레나메토의 사용법을 테스트하기 위해 실체 파일이 없는 상황에서 경로를 만들고 이름을 바꾸는 것을 볼 수 있다.
File t1 = new File("D:" + File.separatorChar + "final.java");
File t2 = new File("D:" + File.separatorChar + "finalaa.java");
System.out.println("       :" + t1.renameTo(t2)); //  false

주의해야 할 것은 new File (filePath) 은 하나의 경로를 얻을 수 있으며, 하나의 실체 파일이 아니다.당신이 파일을 만들지 않았을 때, 어떻게 존재하지 않는 파일의 이름을 바꿀 수 있습니까?
아래와 같이 설명하면 더욱 이해할 수 있다고 생각합니다
new File (String path) 은 파일 자체를 만들지 않고, 이 경로에서 파일을 만들 수도 있다는 것을 이해합니다.
t1이 만들어진 후 (create New File를 호출함) 파일은 그곳에 있습니다.finalaaa로 이름을 바꿉니다.자바 이후 파일은 t1 파일입니다. 경로가 바뀌어서 이름이 바뀌었을 뿐입니다.
처음부터 끝까지 파일이 하나밖에 없다(즉, t2는 장소만 표시했을 뿐 창설되지 않았다. t1이 t2의 땅을 차지하려고 할 때 t2는 t1에게 양보했다)
보조 방법
이름 바꾸기 방법에서 내가 정의한 많은 보조 방법을 호출한 것을 볼 수 있다. 예를 들어 3-1단계
Util.getPathFromFilepath(oldPath); //        (           )

3-2단계
Util.makePath(rootPath, newName); //                 

7단계
Util.getCopyNameFromOriginal(newPath); //              

이러한 방법의 실현도 어렵지 않다. 모두 유틸 패키지에 넣은 것은 복용을 위한 것이다.
    /** * @Description         (           ) * @param filepath        ,like mnt/sda/XX.xx * @return    ,like mnt/sda */
    public static String getPathFromFilepath(final String filepath) {
        int pos = filepath.lastIndexOf('/');
        if (pos != -1) {
            return filepath.substring(0, pos);
        }
        return "";
    }

    /** * @Description       ,          '/'          * @param path1     * @param path2     * @return     */
    public static String makePath(final String path1, final String path2) {
        if (path1.endsWith(File.separator)) {
            return path1 + path2;
        }
        return path1 + File.separator + path2;
    }

위의 두 가지는 확실히 비교적 간단하다. 세 번째 방법getCopyNameFromOriginal(String)은 파일의 복사본 이름을 얻는 것이다. 그 안에 복사본 이름을 정의하는 규칙(빈칸+숫자 증가)이 정의되어 있는데 이 규칙은Mac의 이름 바꾸기 규칙을 본떠서 정의한 것이다.
    /** * @Description         ,               *      :      “ 1”,       “   ”,     。 *   ,     “ .jpg”,         “  1.jpg”,          “  2.jpg” * @param originalName      ,XXX.xx        xx/xx/XXX.xx ,        .xx * @return      */
    public static String getCopyNameFromOriginal(final String originalName) {
        //1.    
        if (originalName == null || originalName.isEmpty()) {
            return null;
        }
        String copyName = null;
        //2.         
        String[] nameAndExt = getNameAndExtFromOriginal(originalName);
        if (nameAndExt == null) {
            return null;
        }
        String fileName = nameAndExt[0];
        String fileExt = nameAndExt[1];
        //3.                      (  )
        if (fileName.contains(" ")) { //         ,             
            //4-1.  end
            String[] array = fileName.split(" ");
            String end = array[array.length - 1]; //          
            //4-2.  end         (                     , :"mnt/sda/wo de/zhao pian/      1.png")
            while(end.contains(" ")) {
                array = fileName.split(" ");
                end = array[array.length - 1];
            }
            //5.                 (     )
            boolean isDigit = end.matches("[0-9]+"); //               
            if (isDigit) {
                try {
                    int index = Integer.parseInt(end) + 1; //      
                    int position = fileName.lastIndexOf(" "); //          ,          
                    if (position != -1) {
                    //6-1.       (    )
                        copyName = fileName.substring(0, position + 1) + String.valueOf(index);
                    }
                } catch (Exception e) { //       
                    e.printStackTrace();
                    return null;
                }
            } else { //          ,            
                //6-2.       (     1)
                copyName = fileName + " 1";
            }
        } else { //    ,         
            //6-3.       (     1)
            copyName = fileName + " 1";
        }
        Log.d(TAG, "new copy name is " + copyName + fileExt);
        //6.     +   
        return copyName + fileExt;
    }

주의해야 할 것은 있다
첫 번째는 모든 표기 문자('')를 추출하여 상수로 저장할 수 있다COPY_NAME_TAG = " ";. 그러면 우리가 표기 문자를 변경하고 싶을 때(예를 들어'-')로 바꾸려면 상수만 바꾸면 된다.
두 번째, 내가 말하고 싶은 것은 다섯 번째 단계boolean isDigit = end.matches("[0-9]+"); // 로 문자열이 숫자인지 아닌지를 어떻게 판단하는지에 관한 것이다.사실 여러 가지 방법이 있다.
1. Character를 사용한다.isDigit 판단
사고방식: 먼저String을char[]로 변환한 다음에 숫자인지 아닌지를 단독으로 판단하고 비트에 따라 값을 산출하며 그렇지 않으면 잘못된 결과(-1)를 출력하고 마지막에 값에 따라 판단한다.
char num[] = end.toCharArray();//           
int result = 0;
for (int i = 0; i < num.length; i++) {
    if (Character.isDigit(num[i])) {
        result += Integer.parseInt(Character.toString(num[i])) * Math.pow(10, length - 1); //          
    } else { //         ,    
        result = -1;
        break;
    }
}
if (result > 0) {
    //...
}

첫 번째 방법은 비교적 간단하고 번거로워서 초보자에게 적합하다.
2. 유형 강제 변환 사용
boolean isDigit;
try {
    int num=Integer.valueOf(end);//           
    isDigit = true;//     ,  True
} catch (Exception e) {
    isDigit = false;//      ,  False
}
if (isDigit) {
    //...
}

이상으로 숫자인지 아닌지를 판단하는 이런 방법은 비교적 괴이하기 때문에 나는 개인적으로 사용을 권장하지 않는다.
3. 정규 표현식으로 판단
바로 나 5단계boolean isDigit = end.matches("[0-9]+"); // 정규 표현식[]은 있을 수 있는지 없는지를 나타낸다. 0-9는 0-9 사이(0과 9 포함)의 모든 숫자를 임의로 선택하고 +는 적어도 한 번은 표시하기 때문에 이렇게 쓰면 정수를 나타낸다.
다음은 네트워크에서 인용한 것으로 정확성을 검증하지 않았습니다.
정규 표현식으로str.matches(regex)가true로 되돌아오는지 확인하면 됩니다.여기서 regex의 부분은 마이너스 정형이 아닌'\d+', 마이너스 번호를 선택할 수 있는'-?\d+, 옵션 플러스 마이너스 사용(?:+|-)?"\d+", 음수가 아닌 부동 소수점 수는 ""\d+(?:\.\d+)?""로 지정합니다."
만약 당신에게 어떤 문제가 있다면, 메시지를 남겨서 저에게 알려 주세요.

좋은 웹페이지 즐겨찾기