Java 在Android上读取内部文件的最佳方式?

Java 在Android上读取内部文件的最佳方式?,java,android,file-io,Java,Android,File Io,我一直在用谷歌搜索一些答案,但似乎找不到最好的答案 以下是迄今为止我在Android上读取内部文件的方法: fis = openFileInput("MY_FILE"); StringBuilder fileContent = new StringBuilder(""); byte[] buffer = new byte[fis.available()]; while (fis.read(buffer) != -1) {

我一直在用谷歌搜索一些答案,但似乎找不到最好的答案

以下是迄今为止我在Android上读取内部文件的方法:

        fis = openFileInput("MY_FILE");
        StringBuilder fileContent = new StringBuilder("");
        byte[] buffer = new byte[fis.available()];
        while (fis.read(buffer) != -1) {
            fileContent.append(new String(buffer));
        }
        MYVARIABLE = fileContent.toString();
        fis.close();
它通常会留下很多空白,但我只是使用了.available方法来只返回我需要的内容

有没有更快或更短的方法来写这个?在API指南中我似乎找不到任何好的。API for表示不应将其用于您需要的目的:

请注意,此方法提供的保证很弱,因此在实践中不是很有用

这意味着它可能不会提供文件大小

2) 。当您在RAM中读取smth时,请考虑文件可能会很长,因此尽量避免花费额外的RAM。为此,使用一个相对较小(1~8KB)的缓冲区从源中读取数据,然后追加到结果中。另一方面,使用太小的缓冲区(比如几个字节)会显著降低读取速度

3) 。读取字节与读取字符不同,因为单个字符可能由多个字节表示(取决于编码)。要读取字符,可以使用spesific类,这些类了解编码并知道如何正确地将字节转换为字符。例如,是这样的类之一

4) 。用于读取的编码应该是用于持久化数据的编码

综上所述,我会像这样使用smth:

public static String getStringFromStream(InputStream in, String encoding) 
        throws IOException {
    InputStreamReader reader;
    if (encoding == null) {
        // This constructor sets the character converter to the encoding
        // specified in the "file.encoding" property and falls back 
        // to ISO 8859_1 (ISO-Latin-1) if the property doesn't exist.
        reader = new InputStreamReader(in);
    } else {
        reader = new InputStreamReader(in, encoding);
    }

    StringBuilder sb = new StringBuilder();

    final char[] buf = new char[1024];
    int len;
    while ((len = reader.read(buf)) > 0) {
        sb.append(buf, 0, len);
    }

    return sb.toString();
}
5) 。确保在使用完
InputStream
后始终将其关闭

当然,在Java/Android中,从文件中读取文本的方法不止一种。这主要是因为JavaAPI包含几代IO API。例如,创建
java.nio
包中的类是为了提高效率,但是通常没有充分的理由使用它们(不要陷入过早的优化sin)。

1)。API for表示不应将其用于您需要的目的:

请注意,此方法提供的保证很弱,因此在实践中不是很有用

这意味着它可能不会提供文件大小

2) 。当您在RAM中读取smth时,请考虑文件可能会很长,因此尽量避免花费额外的RAM。为此,使用一个相对较小(1~8KB)的缓冲区从源中读取数据,然后追加到结果中。另一方面,使用太小的缓冲区(比如几个字节)会显著降低读取速度

3) 。读取字节与读取字符不同,因为单个字符可能由多个字节表示(取决于编码)。要读取字符,可以使用spesific类,这些类了解编码并知道如何正确地将字节转换为字符。例如,是这样的类之一

4) 。用于读取的编码应该是用于持久化数据的编码

综上所述,我会像这样使用smth:

public static String getStringFromStream(InputStream in, String encoding) 
        throws IOException {
    InputStreamReader reader;
    if (encoding == null) {
        // This constructor sets the character converter to the encoding
        // specified in the "file.encoding" property and falls back 
        // to ISO 8859_1 (ISO-Latin-1) if the property doesn't exist.
        reader = new InputStreamReader(in);
    } else {
        reader = new InputStreamReader(in, encoding);
    }

    StringBuilder sb = new StringBuilder();

    final char[] buf = new char[1024];
    int len;
    while ((len = reader.read(buf)) > 0) {
        sb.append(buf, 0, len);
    }

    return sb.toString();
}
5) 。确保在使用完
InputStream
后始终将其关闭


当然,在Java/Android中,从文件中读取文本的方法不止一种。这主要是因为JavaAPI包含几代IO API。例如,来自
java.nio
包的类被创建为更高效的类,但是通常没有充分的理由使用它们(不要陷入过早的优化sin)。

小点:(1)使用此实现,您实际上不需要代理对象(StringBuilder),(2)代码不处理编码,因此,如果文件的内容编码为UTF-8,则可能会获取损坏的数据。@Arhimed-您不必使用StringBuilder,但请记住,在Java中连接字符串很快会变得昂贵,因为Java字符串是一个不可变的对象。这意味着每次在末尾连接一点,实际上(在幕后)必须将整个现有部分复制到一个新的更长字符串对象中,该对象可以包含现有部分和添加的部分。所以在循环中这样做通常是避免的。@Chris Stratton:在这个特定的实现中没有连接-所有数据都在一个块中读取。在这个特定的情况下,while循环只执行一次可能是真的。@Arhimed我应该只使用一个普通的字符串吗?我应该在什么时候处理编码?要点:(1)使用此实现,您实际上不需要代理对象(StringBuilder),(2)代码不处理编码,因此如果文件的内容编码为UTF-8,则可能会获取损坏的数据。@Arhimed-您不必使用StringBuilder,但请记住,在Java中连接字符串很快就会变得昂贵,因为Java字符串是一个不可变的对象。这意味着每次在末尾连接一点,实际上(在幕后)必须将整个现有部分复制到一个新的更长字符串对象中,该对象可以包含现有部分和添加的部分。所以在循环中这样做通常是避免的。@Chris Stratton:在这个特定的实现中没有连接-所有数据都在一个块中读取。在这个特定的情况下,while循环只执行一次可能是真的。@Arhimed我应该只使用一个普通的字符串吗?我应该什么时候处理编码?感谢您的周到和详细的解释:)感谢您的周到和详细的解释:)