Чтение/запись файла во внутреннюю частную память

Я переношу приложение с Symbian/iPhone на Android, частью которого является сохранение некоторых данных в файл. Я использовал FileOutputStream, чтобы сохранить файл в личной папке /data/data/package_name/files:

FileOutputStream fos = iContext.openFileOutput( IDS_LIST_FILE_NAME, Context.MODE_PRIVATE ); 
fos.write( data.getBytes() ); 
fos.close();

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

int ch;
StringBuffer fileContent = new StringBuffer("");
FileInputStream fis = iContext.openFileInput( IDS_LIST_FILE_NAME );
while( (ch = fis.read()) != -1)
  fileContent.append((char)ch);
String data = new String(fileContent);

Итак, мой вопрос: как лучше прочитать файл?


person STeN    schedule 06.03.2011    source источник


Ответы (4)


Использование FileInputStream.read(byte[]) Вы можете читать намного эффективнее.

В общем, вы не хотите считывать в память файлы произвольного размера.

Большинство парсеров примут InputStream. Возможно, вы могли бы сообщить нам, как вы используете файл, и мы могли бы предложить лучший вариант.

Вот как вы используете версию байтового буфера read():

byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
    fileContent.append(new String(buffer));
}
person Matthew Willis    schedule 06.03.2011
comment
Спасибо за ответ, это был и мой первоначальный подход, но мне не удалось получить размер файла... Есть идеи, как я могу получить размер файла? Файл представляет собой какой-то проприетарный формат (позже, если будет время, я конвертирую его в XML и буду использовать InputStream в качестве входных данных для синтаксического анализатора XML DOM/Pull...). - person STeN; 06.03.2011
comment
Вы должны передать FileInputStream непосредственно в ваш анализатор XML. - person Matthew Willis; 06.03.2011
comment
Что касается чтения в байтовый буфер, вы делаете байтовый буфер фиксированного размера, а затем read() в него в цикле. Когда вы дойдете до конца файла, read() сообщит вам об этом в соответствии с документацией. Это распространенный шаблон для ввода/вывода. - person Matthew Willis; 06.03.2011
comment
Я изменил read(byte[], int, int) на read(byte[]), что проще в использовании. - person Matthew Willis; 06.03.2011
comment
Спасибо - отличная поддержка. Кстати, знаете ли вы, можно ли получить доступ к внутреннему частному хранилищу на Android с помощью другого класса, кроме класса FileOutputStream? Например. Файл? Спасибо - person STeN; 06.03.2011
comment
Я так не думаю. Какой еще метод вы бы хотели? File также просто даст вам входной поток. - person Matthew Willis; 06.03.2011
comment
совет: всегда устанавливайте кодировку вручную при создании строки из байтового буфера. IE fileContent.append(new String(buffer, Charset.forName(UTF-8))); - person jocelyn; 30.12.2012
comment
Вы должны указать длину строки, потому что, если вы прочитаете меньше байтов, чем размер буфера при последнем чтении, у вас будет строка выкручивания. Затем установка кодировки вручную при создании строки из байтового буфера является хорошей практикой (min sdk 9): fileContent.append(новая строка(буфер,0, длина, Charset.forName(UTF-8))); - person jocelyn; 30.12.2012

Это не совсем специфично для Android, но больше ориентировано на Java.

Если вместо этого вы предпочитаете построчное чтение, вы можете обернуть FileInputStream в InputStreamReader, который затем можно передать в BufferedReader. Экземпляр BufferedReader имеет метод readLine(), который вы можете использовать для чтения построчно.

InputStreamReader in = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(in);
String data = br.readLine()

В качестве альтернативы, если вы используете библиотеку Google Guava, вы можете использовать вспомогательную функцию в ByteStreams:

String data = new String(ByteStreams.toByteArray(fis));
person Roshan    schedule 06.03.2011

//написать

String data = "Hello World";
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput(FILENAME,     
Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();

//читать

String ret = "";

    try {
        InputStream inputStream = openFileInput(FILENAME);

        if ( inputStream != null ) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String receiveString = "";
            StringBuilder stringBuilder = new StringBuilder();

            while ( (receiveString = bufferedReader.readLine()) != null ) {
                stringBuilder.append(receiveString);
            }

            inputStream.close();
            ret = stringBuilder.toString();
        }
    }
    catch (FileNotFoundException e) {
        Log.e(TAG, "File not found: " + e.toString());
    } catch (IOException e) {
        Log.e(TAG, "Can not read file: " + e.toString());
    }

    return ret;
}
person user3819148    schedule 23.09.2014

context.getFilesDir() возвращает объект File каталога, в котором context.openFileOutput() выполнил запись файла.

person CodeToLife    schedule 05.05.2018