Java: проблемы с доступом и записью в файл

Я тестировал запись в файлы с помощью этого кода:

package files;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;

public class FileTest1 
{
public static void main(String[] args)
{
    try
    {
        try
        {
            File f = new File("filetest1.txt");
            FileWriter fWrite = new FileWriter(f);
            BufferedWriter fileWrite = new BufferedWriter(fWrite);
            fileWrite.write("This is a test!");
        }
        catch(FileNotFoundException e)
        {
            System.out.print("A FileNotFoundException occurred!");
            e.printStackTrace();
        }
    }
    catch(IOException e)
    {
        System.out.println("An IOException occurred!:");
        e.printStackTrace();
    }
}

}

При его выполнении ничего не происходит. "Это проверка!" не написано, ни StackTrace, ни «A/An [исключение] произошло!»... Я не знаю, в чем причина проблемы. У меня есть файл Test1.txt в пакете прямо под файлом...


person user2604533    schedule 16.08.2013    source источник
comment
Ваш код говорит filetest1.txt, а ваш комментарий говорит fileTest1.txt? Большинство файловых систем чувствительны к регистру. Возможно, вы также захотите сбросить файл, а затем закрыть его.   -  person Hyperboreus    schedule 17.08.2013
comment
Можете ли вы показать команду, которую вы используете для запуска вашей программы? Вы делаете это, бросаете какую-то IDE? На какой платформе вы работаете? Кроме того, вы говорите, что у меня есть файл Test1.txt в пакете прямо под файлом — можете ли вы пояснить, что это значит?   -  person Jason C    schedule 17.08.2013
comment
Кроме того, вы уверены, что на самом деле запускаете программу, которую, по вашему мнению, запускаете? Вы действительно работаете FileTest1? Добавьте System.println("Hello"); или что-то в качестве первой строки файла main. Он отображается? Рабочий каталог отличается от ожидаемого? filetest1.txt создается где-то еще?   -  person Jason C    schedule 17.08.2013


Ответы (4)


BufferedWriter делает именно это, он буферизует вывод до того, как он будет записан в место назначения. Это может сделать BufferedWriter более быстрым в использовании, поскольку ему не нужно сразу записывать в медленное место назначения, например, на диск или сокет.

Содержимое будет записано, когда внутренний буфер будет заполнен, вы flush Writer или close пишущий

Помните, если вы открыли его, вы должны закрыть его...

Например...

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestFileWriter {

    public static void main(String[] args) {
        try {
            BufferedWriter fileWrite = null;
            try {
                File f = new File("filetest1.txt");
                System.out.println("Writing to " + f.getCanonicalPath());
                FileWriter fWrite = new FileWriter(f);
                fileWrite = new BufferedWriter(fWrite);
                fileWrite.write("This is a test!");
                fileWrite.flush();
            } catch (FileNotFoundException e) {
                System.out.print("A FileNotFoundException occurred!");
                e.printStackTrace();
            } finally {
                try {
                    // Note, BufferedWriter#close will also close
                    // the parent Writer...
                    fileWrite.close();
                } catch (Exception exp) {
                }
            }
        } catch (IOException e) {
            System.out.println("An IOException occurred!:");
            e.printStackTrace();
        }
        try {
            BufferedReader br = null;
            try {
                File f = new File("filetest1.txt");
                System.out.println("Reading from " + f.getCanonicalPath());
                FileReader fReader = new FileReader(f);
                br = new BufferedReader(fReader);
                String text = null;
                while ((text = br.readLine()) != null) {
                    System.out.println(text);
                }
            } catch (FileNotFoundException e) {
                System.out.print("A FileNotFoundException occurred!");
                e.printStackTrace();
            } finally {
                try {
                    // Note, BufferedWriter#close will also close
                    // the parent Writer...
                    br.close();
                } catch (Exception exp) {
                }
            }
        } catch (IOException e) {
            System.out.println("An IOException occurred!:");
            e.printStackTrace();
        }
    }
}

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

person MadProgrammer    schedule 16.08.2013
comment
Хорошо... Я исправил заглавные буквы и добавил: fileWriter.flush() и fileWriter.close(), но все равно ничего не происходит. - person user2604533; 17.08.2013
comment
Я написал это в, но все равно ничего не произошло. - person user2604533; 17.08.2013
comment
Могу ли я попросить вас попробовать мой пример кода. Потому что он отлично работает для меня. Кроме того, убедитесь, что у вас есть доступ для записи к месту, куда вы пытаетесь записать... - person MadProgrammer; 17.08.2013
comment
Я бы предположил, что вы пытаетесь записать в место, к которому у вас нет доступа для записи. Убедитесь, что вы удаляете только старые filetest1.txt файлы и убедитесь, что вы записываете в место, куда, как вы знаете, вы можете писать - person MadProgrammer; 17.08.2013
comment
Я думаю, что OP проверяет другой файл с тем же именем, а не файл, в который записывается. - person jlordo; 17.08.2013
comment
@MadProgrammer Проблемы с разрешениями вызовут исключение. - person Jason C; 17.08.2013
comment
@ user2604533: Можете ли вы показать команду, которую вы используете для запуска своей программы? Вы делаете это через какую-то IDE? На какой платформе вы работаете? Кроме того, вы говорите, что у меня есть файл Test1.txt в пакете прямо под файлом — можете ли вы пояснить, что это значит? Вы уверены, что на самом деле запускаете программу, которую, по вашему мнению, запускаете? Вы действительно работаете FileTest1? Добавьте System.println("Hello"); или что-то в качестве первой строки файла main. Он отображается? Рабочий каталог отличается от ожидаемого? filetest1.txt создается где-то еще? - person Jason C; 17.08.2013
comment
@JasonC Не в Windows 7: P - Была эта проблема, нам потребовалось две недели, чтобы понять это: P - person MadProgrammer; 17.08.2013
comment
@MadProgrammer Я никогда не припомню, чтобы сталкивался с такой проблемой в Windows 7, но я на 100% верю в это. - person Jason C; 17.08.2013
comment
@user2604533 user2604533 Я обновил свой пример, чтобы напечатать абсолютный путь к записываемому файлу, чтобы вы без сомнения знали, где начинается запись файла. Я также добавил тест чтения, чтобы прочитать файл обратно в - person MadProgrammer; 17.08.2013
comment
Если исключение не выдается из-за ошибки отказа в доступе, возможно, файл существует, но открыт каким-то другим процессом; возможно, предыдущий запуск его программы или текстового редактора. Он говорит, что у него уже где-то есть файл test1.txt. - person Jason C; 17.08.2013
comment
@JasonC Наше приложение пыталось записывать файлы в каталог Program Files от имени обычного пользователя, и файлы просто не записывались, хотя File#canWrite возвращал true - оказывается, это ошибка в Java с UAC - я бы хотел те две недели моей жизни назад :P - person MadProgrammer; 17.08.2013
comment
Странный. Удалил файл filetest1.txt из проводника пакетов в eclipse, затем просмотрел его в строке поиска, чтобы найти его все еще существующим, с помощью этого теста! написано в нем, но я не могу редактировать его дальше... - person user2604533; 17.08.2013
comment
@MadProgrammer Увлекательно; и я регистрирую это (не)взаимодействие Java/UAC. Возможно, вы сэкономили мне две недели в какой-то неизвестный момент в будущем. Обычно я сразу отключаю UAC на каждой машине, которую настраиваю. - person Jason C; 17.08.2013
comment
@ user2604533: Вы не сказали, что просматриваете его в браузере Eclipse! Eclipse иногда просто воняет из-за обновления ресурсов, которые изменены вне редактора ... Я бы просто очистил ваш проект, затем перезапустил Eclipse и посмотрел, имеет ли после этого смысл. - person Jason C; 17.08.2013
comment
@JasonC Да, на наших машинах разработчиков был отключен UAC, поэтому у нас все работало нормально, но когда мы попытались развернуть на клиентской машине, он сломался ...: P - person MadProgrammer; 17.08.2013
comment
@MadProgrammer Примите мои глубочайшие соболезнования. - person Jason C; 17.08.2013
comment
@JasonC Я понял :) В меню «Пуск» я увидел, что всякий раз, когда я запускаю программу, она создает новую версию файла в другом месте проекта eclipse, поэтому я поместил ее туда, и она сработала. - person user2604533; 17.08.2013

После

fileWrite.write("This is a test!");

вы должны flush() писателя. Чтобы избежать утечки ресурсов, вы также должны close() записать (что автоматически сбрасывает его).

Итак, вам нужно добавить:

fileWrite.close();
person jlordo    schedule 16.08.2013

Используйте BufferedWriter.flush() и BufferedWriter.close(). Дополнительная информация здесь http://docs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html

person blgt    schedule 16.08.2013

Вы должны вызвать close() или хотя бы flush() на модуле записи, чтобы буфер действительно был записан в файл.

person FrankPl    schedule 16.08.2013
comment
Вы должны всегда закрывать любой ресурс, который вы открываете, это может вызвать проблемы позже - ИМХО - person MadProgrammer; 17.08.2013
comment
Я согласен, и я бы даже сделал это в finally, чтобы быть действительно уверенным. Но вопрос был в том, почему данные не видны, и что можно добраться только через flush(). - person FrankPl; 17.08.2013
comment
(придирка) На самом деле всю проблему можно решить, просто позвонив close, что не только помогает решить проблему ОП, но и демонстрирует передовой опыт. Если бы ОП писал на Socket, он демонстративно согласился бы с добавлением flush - ИМХО - person MadProgrammer; 17.08.2013