Android читает текстовый необработанный файл ресурсов


123

Все просто, но не работает должным образом.

У меня есть текстовый файл, добавленный как необработанный ресурс. Текстовый файл содержит текст вроде:

b) ЕСЛИ ПРИМЕНИМЫМ ЗАКОНОДАТЕЛЬСТВОМ ТРЕБУЮТСЯ КАКИЕ-ЛИБО ГАРАНТИИ В ОТНОШЕНИИ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ВСЕ ТАКИЕ ГАРАНТИИ ОГРАНИЧИВАЮТСЯ ДЕЙСТВИЕМ ДЕВЯТЬ (90) ДНЕЙ С ДАТЫ ПОСТАВКИ.

(c) НИКАКАЯ УСТНАЯ ИЛИ ПИСЬМЕННАЯ ИНФОРМАЦИЯ ИЛИ СОВЕТЫ, ДАННЫЕ VIRTUAL ORIENTEERING, ЕГО ДИЛЕРЫ, ДИСТРИБЬЮТОРЫ, АГЕНТЫ ИЛИ СОТРУДНИКИ, НЕ СОЗДАЮТ ГАРАНТИИ ИЛИ ЛЮБЫМ СПОСОБОМ РАСШИРЯЮТ ОБЪЕМ ЛЮБОЙ ГАРАНТИИ, ПРЕДОСТАВЛЕННОЙ ЗДЕСЬ.

(d) (только для США) В НЕКОТОРЫХ ШТАТАХ НЕ ДОПУСКАЕТСЯ ИСКЛЮЧЕНИЕ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ, ПОЭТОМУ ВЫШЕУКАЗАННОЕ ИСКЛЮЧЕНИЕ МОЖЕТ К ВАМ НЕ ОТНОСИТЬСЯ. НАСТОЯЩАЯ ГАРАНТИЯ ПРЕДОСТАВЛЯЕТ ВАМ КОНКРЕТНЫЕ ЮРИДИЧЕСКИЕ ПРАВА, И ВЫ ТАКЖЕ МОЖЕТЕ ИМЕТЬ ДРУГИЕ ЮРИДИЧЕСКИЕ ПРАВА, КОТОРЫЕ РАЗЛИЧАЮТСЯ В РАЗНЫХ ШТАТАХ.

На моем экране такой макет:

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
                     android:layout_width="fill_parent" 
                     android:layout_height="wrap_content" 
                     android:gravity="center" 
                     android:layout_weight="1.0"
                     android:layout_below="@+id/logoLayout"
                     android:background="@drawable/list_background"> 

            <ScrollView android:layout_width="fill_parent"
                        android:layout_height="fill_parent">

                    <TextView  android:id="@+id/txtRawResource" 
                               android:layout_width="fill_parent" 
                               android:layout_height="fill_parent"
                               android:padding="3dip"/>
            </ScrollView>  

    </LinearLayout>

Код для чтения необработанного ресурса:

TextView txtRawResource= (TextView)findViewById(R.id.txtRawResource);

txtDisclaimer.setText(Utils.readRawTextFile(ctx, R.raw.rawtextsample);

public static String readRawTextFile(Context ctx, int resId)
{
    InputStream inputStream = ctx.getResources().openRawResource(resId);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    int i;
    try {
        i = inputStream.read();
        while (i != -1)
        {
            byteArrayOutputStream.write(i);
            i = inputStream.read();
        }
        inputStream.close();
    } catch (IOException e) {
        return null;
    }
    return byteArrayOutputStream.toString();
}

Текст отображается, но после каждой строки появляется странный символ [] Как я могу удалить этот символ? Думаю, это New Line.

РАБОЧЕЕ РЕШЕНИЕ

public static String readRawTextFile(Context ctx, int resId)
{
    InputStream inputStream = ctx.getResources().openRawResource(resId);

    InputStreamReader inputreader = new InputStreamReader(inputStream);
    BufferedReader buffreader = new BufferedReader(inputreader);
    String line;
    StringBuilder text = new StringBuilder();

    try {
        while (( line = buffreader.readLine()) != null) {
            text.append(line);
            text.append('\n');
        }
    } catch (IOException e) {
        return null;
    }
    return text.toString();
}

3
Подсказка: вы можете аннотировать свой параметр rawRes с помощью @RawRes, чтобы Android Studio ожидала необработанные ресурсы.
Roel

Рабочее решение должно быть опубликовано как ответ, где за него можно проголосовать.
LarsH

Ответы:


65

Что если вы используете BufferedReader на основе символов вместо InputStream на основе байтов?

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine();
while (line != null) { ... }

Не забывайте, что readLine()новые строки пропускаются!


162

Вы можете использовать это:

    try {
        Resources res = getResources();
        InputStream in_s = res.openRawResource(R.raw.help);

        byte[] b = new byte[in_s.available()];
        in_s.read(b);
        txtHelp.setText(new String(b));
    } catch (Exception e) {
        // e.printStackTrace();
        txtHelp.setText("Error: can't show help.");
    }

5
Я не уверен, что Inputstream.available () здесь правильный выбор, скорее прочитайте n в ByteArrayOutputStream до n == -1.
ThomasRS

15
Это может не работать для больших ресурсов. Это зависит от размера буфера чтения входного потока и может возвращать только часть ресурса.
d4n3

6
@ d4n3 прав, документация по доступному методу входного потока гласит: «Возвращает приблизительное количество байтов, которые можно прочитать или пропустить без блокировки для большего ввода. Обратите внимание, что этот метод дает такую ​​слабую гарантию, что он не очень полезен в практика »
ozba

Посмотрите документы Android для InputStream.available. Если я правильно понимаю, они говорят, что его нельзя использовать для этой цели. Кто бы мог подумать, что так сложно прочитать содержание дурацкого файла ...
Анхопп,

2
И не стоит ловить общее исключение. Вместо этого перехватите IOException.
alcsan

30

Если вы используете IOUtils из apache "commons-io", это еще проще:

InputStream is = getResources().openRawResource(R.raw.yourNewTextFile);
String s = IOUtils.toString(is);
IOUtils.closeQuietly(is); // don't forget to close your streams

Зависимости: http://mvnrepository.com/artifact/commons-io/commons-io

Maven:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

Gradle:

'commons-io:commons-io:2.4'

1
Что мне нужно импортировать, чтобы использовать IOUtils?
ЕСФУЛ

1
Библиотека Apache commons-io ( commons.apache.org/proper/commons-io ). Или если вы используете Maven ( mvnrepository.com/artifact/commons-io/commons-io ).
tbraun

8
Для gradle: скомпилируйте "commons-io: commons-io: 2.1"
JustinMorris

9
Но в целом импорт внешних сторонних библиотек во избежание написания еще трех строк кода ... кажется излишним.
milosmns

12

Что ж, с Kotlin вы можете сделать это всего в одной строке кода:

resources.openRawResource(R.raw.rawtextsample).bufferedReader().use { it.readText() }

Или даже объявить функцию расширения:

fun Resources.getRawTextFile(@RawRes id: Int) =
        openRawResource(id).bufferedReader().use { it.readText() }

А потом сразу же используйте:

val txtFile = resources.getRawTextFile(R.raw.rawtextsample)


Это единственное, что у меня сработало! Спасибо!
fuomag9

Ницца! Вы сделали мой день!
cesards

3

Скорее сделайте это так:

// reads resources regardless of their size
public byte[] getResource(int id, Context context) throws IOException {
    Resources resources = context.getResources();
    InputStream is = resources.openRawResource(id);

    ByteArrayOutputStream bout = new ByteArrayOutputStream();

    byte[] readBuffer = new byte[4 * 1024];

    try {
        int read;
        do {
            read = is.read(readBuffer, 0, readBuffer.length);
            if(read == -1) {
                break;
            }
            bout.write(readBuffer, 0, read);
        } while(true);

        return bout.toByteArray();
    } finally {
        is.close();
    }
}

    // reads a string resource
public String getStringResource(int id, Charset encoding) throws IOException {
    return new String(getResource(id, getContext()), encoding);
}

    // reads an UTF-8 string resource
public String getStringResource(int id) throws IOException {
    return new String(getResource(id, getContext()), Charset.forName("UTF-8"));
}

Из Activity добавьте

public byte[] getResource(int id) throws IOException {
        return getResource(id, this);
}

или из тестового примера добавьте

public byte[] getResource(int id) throws IOException {
        return getResource(id, getContext());
}

И следите за обработкой ошибок - не перехватывайте и не игнорируйте исключения, когда ваши ресурсы должны существовать или что-то (очень?) Не так.


Вам нужно закрыть поток, открытый пользователем openRawResource()?
Alex Semeniuk

Не знаю, но это, конечно, стандарт. Обновление примеров.
ThomasRS

2

Это еще один метод, который определенно сработает, но я не могу заставить его читать несколько текстовых файлов для просмотра в нескольких текстовых представлениях в одном действии, кто-нибудь может помочь?

TextView helloTxt = (TextView)findViewById(R.id.yourTextView);
    helloTxt.setText(readTxt());
}

private String readTxt(){

 InputStream inputStream = getResources().openRawResource(R.raw.yourTextFile);
 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

 int i;
try {
i = inputStream.read();
while (i != -1)
  {
   byteArrayOutputStream.write(i);
   i = inputStream.read();
  }
  inputStream.close();
} catch (IOException e) {
 // TODO Auto-generated catch block
e.printStackTrace();
}

 return byteArrayOutputStream.toString();
}

2

@borislemke, вы можете сделать это аналогичным образом, например

TextView  tv ;
findViewById(R.id.idOfTextView);
tv.setText(readNewTxt());
private String readNewTxt(){
InputStream inputStream = getResources().openRawResource(R.raw.yourNewTextFile);
 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

 int i;
 try {
 i = inputStream.read();
while (i != -1)
  {
   byteArrayOutputStream.write(i);
   i = inputStream.read();
   }
    inputStream.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
 e.printStackTrace();
 }

 return byteArrayOutputStream.toString();
 }

2

Вот смесь решений Weekens и Vovodroid.

Это правильнее, чем решение Вводроида, и более полно, чем решение Weekens.

    try {
        InputStream inputStream = res.openRawResource(resId);
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                StringBuilder result = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    result.append(line);
                }
                return result.toString();
            } finally {
                reader.close();
            }
        } finally {
            inputStream.close();
        }
    } catch (IOException e) {
        // process exception
    }

2

Вот простой способ прочитать текстовый файл из необработанной папки:

public static String readTextFile(Context context,@RawRes int id){
    InputStream inputStream = context.getResources().openRawResource(id);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    byte buffer[] = new byte[1024];
    int size;
    try {
        while ((size = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, size);
        }
        outputStream.close();
        inputStream.close();
    } catch (IOException e) {

    }
    return outputStream.toString();
}

2

Вот реализация в Котлине

    try {
        val inputStream: InputStream = this.getResources().openRawResource(R.raw.**)
        val inputStreamReader = InputStreamReader(inputStream)
        val sb = StringBuilder()
        var line: String?
        val br = BufferedReader(inputStreamReader)
        line = br.readLine()
        while (line != null) {
            sb.append(line)
            line = br.readLine()
        }
        br.close()

        var content : String = sb.toString()
        Log.d(TAG, content)
    } catch (e:Exception){
        Log.d(TAG, e.toString())
    }

1

1. Сначала создайте папку Directory и назовите ее raw внутри папки res 2. создайте файл .txt внутри папки raw-каталога, которую вы создали ранее, и дайте ему любое имя, например, articles.txt .... 3. скопируйте и вставьте файл текст, который вы хотите внутри .txt файла, который вы создали "article.txt" 4. не забудьте включить текстовое представление в свой main.xml MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gettingtoknowthe_os);

    TextView helloTxt = (TextView)findViewById(R.id.gettingtoknowos);
    helloTxt.setText(readTxt());

    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();//to exclude the ActionBar
}

private String readTxt() {

    //getting the .txt file
    InputStream inputStream = getResources().openRawResource(R.raw.articles);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    try {
        int i = inputStream.read();
        while (i != -1) {
            byteArrayOutputStream.write(i);
            i = inputStream.read();
        }
        inputStream.close();

    } catch (IOException e) {
        e.printStackTrace();
    }
    return byteArrayOutputStream.toString();
}

Надеюсь, это сработало!


1
InputStream is=getResources().openRawResource(R.raw.name);
BufferedReader reader=new BufferedReader(new InputStreamReader(is));
StringBuffer data=new StringBuffer();
String line=reader.readLine();
while(line!=null)
{
data.append(line+"\n");
}
tvDetails.seTtext(data.toString());
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.