Java-файл нельзя ни удалить, ни переименовать

Смотрите мой код ниже: я могу написать ключ и строку в одной строке файла. Если ключ уже существует, я хочу перезаписать его, создав новый файл и заполнив его содержимым исходного файла. В конце я собираюсь удалить старый файл и переименовать свой временный файл. Но это не работает. Как видите, я печатаю логические значения для методов удаления и переименования. Оба возвращаются как "false".

Я читал в некоторых других темах, что я должен закрыть все программы чтения и записи, которые контактируют с моим файлом, чтобы иметь возможность переименовать или удалить его.

Ты видишь мою ошибку?

(Обратите внимание, что некоторые комментарии написаны на немецком языке)

public static boolean dini_Set(String filepath, String key, String value) throws IOException
{
    if(key.length() <= 0 || value.length() <= 0) return false;

    String pfilepath = rootdirectory.concat(filepath);
    File pfile = new File(pfilepath);
    //dini_Remove(filepath.concat(".part"));

    if(dini_Exists(filepath) == false) return false;

    // Checkt ob der Key schon existiert

    FileReader fr = new FileReader(pfilepath);
    BufferedReader br = new BufferedReader(fr);

    String ausw;
    boolean foundkeybool = false;
    while((ausw = br.readLine()) != null)
    {
       String foundkey = ausw.substring(0,ausw.indexOf("="));
       //System.out.println(foundkey);
       if(foundkey.equals(key))
       {
           foundkeybool = true;
           System.out.println(foundkeybool);

           // Key exists and content has to be overwritten

           String newline = key.concat("=").concat(value);

           String tmpdir = rootdirectory.concat("tmp.tmp");
           File tmp = new File(tmpdir);
           tmp.createNewFile();
           String currentLine;
           FileWriter fw = new FileWriter(tmpdir);
           BufferedWriter bw = new BufferedWriter(fw);

           br.close();
           fr.close();

           fr = new FileReader(pfilepath);
           br = new BufferedReader(fr);

           while((currentLine = br.readLine()) != null) 
           {
                // trim newline when comparing with lineToRemove
                String trimmedLine = currentLine.trim();
                System.out.println(trimmedLine);
                if(trimmedLine.equals(ausw)) 
                {
                    System.out.println("Austauschen: "+newline);
                    bw.write(newline);
                }
                else
                {
                    bw.write(currentLine);
                    System.out.println("Lassen: "+currentLine);
                }
                bw.newLine();
           }

           br.close();
           fr.close();
           bw.close();
           fw.close();
           tmp.setWritable(true);
           pfile.setWritable(true);
           // boolean removed = dini_Remove(filepath);
           boolean removed = pfile.delete();
           System.out.println("Datei wurde gelöscht: "+removed);
           boolean renamed = tmp.renameTo(pfile);
           System.out.println("Datei umbenannt: "+renamed);
           break;
       }
    }

    // if key does now exists we can create a new one
    if(foundkeybool == false)
    {
        FileWriter fw = new FileWriter(pfilepath,true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(key.concat("=").concat(value));
        bw.newLine();
        bw.close();
    }   
    return true;
}

person Felix Hageneier    schedule 23.07.2013    source источник


Ответы (2)


Это может не решить вашу проблему, но приблизит вас к ней.

Вы ДОЛЖНЫ убедиться, что любой ресурс, который вы открываете, закрыт должным образом. В настоящее время в вашем коде, если по какой-то причине возникает исключение, ни один из ваших ресурсов не будет закрыт.

Даже если вы не заинтересованы в обработке исключения внутри метода, вы все равно должны заключить код доступа к файлу в блок try-finally.

FileReader fr = null;
BufferedReader br = null;
try {
    fr = new FileReader(pfilepath);
    br = new BufferedReader(fr);    
    //...//
} finally {
    try {
        br.close();
    } catch (Exception exp) {
    }
    try {
        fr.close();
    } catch (Exception exp) {
    }
}

Вы можете обнаружить, что вам нужно только закрыть BufferedReader, и он должен вызывать close на своем дочернем элементе Reader, но я параноик в том, чтобы убедиться, что все чисто

Если вы используете Java 7, вы можете взглянуть на попробовать Заявление -with-resources

Обновлено

Я не уверен, что ваш код имеет смысл. По сути, то, что вы должны делать, это читать весь исходный файл и записывать его во временное местоположение (поскольку вы не знаете заранее, нужно ли обновлять ключ, и вам, вероятно, все равно придется читать исходный файл, чтобы найти из).

После того, как это будет завершено, если вы внесли изменения во временный файл, удалите исходный файл и переименуйте временный файл на его место.

Ваш код кажется мне очень неэффективным...

person MadProgrammer    schedule 23.07.2013

Хорошо, я хочу дать вам краткую информацию о коде.

Я изменил его таким образом, и пока он работает как надо.

У вас есть еще что-то, что я могу изменить, чтобы оптимизировать код?

public static boolean dini_Set(String filepath, String key, String value) throws IOException
{
    if(key.length() <= 0 || value.length() <= 0) return false;

    String pfilepath = rootdirectory.concat(filepath);
    File pfile = new File(pfilepath);
    //dini_Remove(filepath.concat(".part"));

    if(dini_Exists(filepath) == false) return false;

    // Checkt ob der Key schon existiert

    boolean foundkeybool = false;
    File tmp = null;

    try(BufferedReader br = new BufferedReader(new FileReader(pfilepath)))
    {           
        String ausw;

        while((ausw = br.readLine()) != null)
        {
           String foundkey = ausw.substring(0,ausw.indexOf("="));
           System.out.println(foundkey);
           if(foundkey.equals(key))
           {
               foundkeybool = true;
               System.out.println(foundkeybool);

               //Key exists and content has to be overwritten

               String newline = key.concat("=").concat(value);

               String tmpdir = rootdirectory.concat("tmp.tmp");
               tmp = new File(tmpdir);
               tmp.createNewFile();
               String currentLine;

               try(BufferedWriter bw = new BufferedWriter(new FileWriter(tmpdir)))
               {
                   try(BufferedReader br2 = new BufferedReader(new FileReader(pfilepath)))                
                   {
                       while((currentLine = br2.readLine()) != null) 
                       {
                            //trim newline when comparing with lineToRemove
                            String trimmedLine = currentLine.trim();
                            System.out.println(trimmedLine);
                            if(trimmedLine.equals(ausw)) 
                            {
                                System.out.println("Austauschen: "+newline);
                                bw.write(newline);
                            }
                            else
                            {
                                bw.write(currentLine);
                                System.out.println("Lassen: "+currentLine);
                            }
                            bw.newLine();
                       }
                   }
               }    



               break;
           }
        }
    }

    if(foundkeybool == true)
    {
        tmp.setWritable(true);
       pfile.setWritable(true);
       //boolean removed = dini_Remove(filepath);
       boolean removed = pfile.delete();
       System.out.println("Datei wurde gelöscht: "+removed);
       boolean renamed = tmp.renameTo(pfile);
       System.out.println("Datei umbenannt: "+renamed);
    }
    else //(foundkeybool == false) if key does now exists we can create a new one
    {
        try(BufferedWriter bw = new BufferedWriter(new FileWriter(pfilepath,true)))
        {
            bw.write(key.concat("=").concat(value));
            bw.newLine();
            bw.close();
        }     
    }   
    return true;
}
person Felix Hageneier    schedule 23.07.2013