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()новые строки пропускаются!

weekens
источник
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.");
    }
Vovodroid
источник
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'
tbraun
источник
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());
}

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

ThomasRS
источник
Вам нужно закрыть поток, открытый пользователем 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();
}
borislemke
источник
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
    }
alcsan
источник
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();
}
ucMedia
источник
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();
}

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

Frankrnz
источник
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());
сакши агравал
источник