读取文件为字符串

Pan*_*nos 51 string optimization android

我需要在android中加载一个xml文件作为String,这样我就可以将它加载到TBXML xml解析器库并解析它.我现在将文件读取为String的实现大约需要2秒,即使对于某些KB的非常小的xml文件也是如此.有没有已知的快速方法可以在Java/Android中将文件读取为字符串?


这是我现在的代码:

public static String readFileAsString(String filePath) {
    String result = "";
    File file = new File(filePath);
    if ( file.exists() ) {
        //byte[] buffer = new byte[(int) new File(filePath).length()];
        FileInputStream fis = null;
        try {
            //f = new BufferedInputStream(new FileInputStream(filePath));
            //f.read(buffer);

            fis = new FileInputStream(file);
            char current;
            while (fis.available() > 0) {
                current = (char) fis.read();
                result = result + String.valueOf(current);
            }
        } catch (Exception e) {
            Log.d("TourGuide", e.toString());
        } finally {
            if (fis != null)
                try {
                    fis.close();
                } catch (IOException ignored) {
            }
        }
        //result = new String(buffer);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

Pan*_*nos 137

最终使用的代码如下:

http://www.java2s.com/Code/Java/File-Input-Output/ConvertInputStreamtoString.htm

public static String convertStreamToString(InputStream is) throws Exception {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
      sb.append(line).append("\n");
    }
    reader.close();
    return sb.toString();
}

public static String getStringFromFile (String filePath) throws Exception {
    File fl = new File(filePath);
    FileInputStream fin = new FileInputStream(fl);
    String ret = convertStreamToString(fin);
    //Make sure you close all streams.
    fin.close();        
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

  • 我的第一个fn关闭它没有打开的流似乎不对我.换句话说,我认为getStringFromFile应该关闭流. (4认同)
  • 轻微警告:你应该关闭阅读器. (4认同)
  • 这不会在字符串末尾添加额外的新行吗? (3认同)
  • @Tom实际上,这个答案的重要部分是展示循环中发生的事情并创建字符串.无论如何,你是对的,在getStringFromFile中关闭流更好,所以我编辑了答案.谢谢. (2认同)

Eug*_*nyk 15

你可以org.apache.commons.io.IOUtils.toString(InputStream is, Charset chs)用来做那件事.

例如

IOUtils.toString(context.getResources().openRawResource(<your_resource_id>), StandardCharsets.UTF_8)
Run Code Online (Sandbox Code Playgroud)

要添加正确的库:

将以下内容添加到app/build.gradle文件中:

dependencies {
    compile 'org.apache.directory.studio:org.apache.commons.io:2.4'
}
Run Code Online (Sandbox Code Playgroud)

或者对于Maven回购看 - > 这个链接

对于直接jar下载,请参阅 - > https://commons.apache.org/proper/commons-io/download_io.cgi


Cra*_*lWS 15

重写了源自 - > 接受的答案的方法集

@JaredRummler您的评论的答案:

读取文件为字符串

这不会在字符串末尾添加额外的新行吗?

为了防止在最后添加换行符,您可以像在代码示例中一样使用在第一个循环期间设置的布尔值 Boolean firstLine

public static String convertStreamToString(InputStream is) throws IOException {
   // http://www.java2s.com/Code/Java/File-Input-Output/ConvertInputStreamtoString.htm
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;
    Boolean firstLine = true;
    while ((line = reader.readLine()) != null) {
        if(firstLine){
            sb.append(line);
            firstLine = false;
        } else {
            sb.append("\n").append(line);
        }
    }
    reader.close();
    return sb.toString();
}

public static String getStringFromFile (String filePath) throws IOException {
    File fl = new File(filePath);
    FileInputStream fin = new FileInputStream(fl);
    String ret = convertStreamToString(fin);
    //Make sure you close all streams.
    fin.close();
    return ret;
}
Run Code Online (Sandbox Code Playgroud)


小智 6

对于文件,我们事先知道大小,所以只需一次阅读!

String result;
File file = ...;

long length = file.length();
if (length < 1 || length > Integer.MAX_VALUE) {
    result = "";
    Log.w(TAG, "File is empty or huge: " + file);
} else {
    try (FileReader in = new FileReader(file)) {
        char[] content = new char[(int)length];

        int numRead = in.read(content);
        if (numRead != length) {
            Log.e(TAG, "Incomplete read of " + file + ". Read chars " + numRead + " of " + length);
        }
        result = new String(content, 0, numRead);
    }
    catch (Exception ex) {
        Log.e(TAG, "Failure reading " + this.file, ex);
        result = "";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这会被否决。当然,代码很杂乱,但这会起作用(如果他为大文件分配缓冲区内存不足,那么使用 StringBuffer 的示例也会如此)。它也不会添加额外的换行符,这是最高投票的答案所做的。 (2认同)

vov*_*ost 6

如果你使用 Kotlin,这很容易:

val textFile = File(cacheDir, "/text_file.txt")
val allText = textFile.readText()
println(allText)
Run Code Online (Sandbox Code Playgroud)

readText()文档:

使用 UTF-8 或指定字符集以字符串形式获取此文件的全部内容。不建议在大文件上使用此方法。它具有 2 GB 文件大小的内部限制。

  • @StealthRabbi 在这个问题中,操作员询问如何在 Java/Android 中做到这一点。当时 Java 是 Android 的主要语言,因此现在发布 Kotlin 版本是有意义的。此外,问题标签仅包括 Android,我认为这是更重要的。 (4认同)
  • 是的,他没有使用 Java 标签,因为考虑到问题提出的时间,这是假设的。这就像 1870 年我问如何在城市之间快速旅行,100 年后你回答我坐飞机一样。 (4认同)
  • @StealthRabbi 对于 100 年后阅读上述假设问题的人来说,乘坐飞机是公认的正确答案。 (4认同)
  • 他没有使用 Kotlin。问题是针对 Java 的。 (2认同)
  • 我在 1800 年代写了最初的问题。我们当时得到了一些很好的解决方案。但这也是一个非常好的可接受的解决方案,因此我们可以看到 JVM api 和解决方案的演变 (2认同)