以字符串形式读取文件

Posted

技术标签:

【中文标题】以字符串形式读取文件【英文标题】:Read file As String 【发布时间】:2012-10-06 07:19:33 【问题描述】:

我需要在 android 中将 xml 文件作为字符串加载,以便将其加载到 TBXML xml 解析器库并解析它。即使对于一些 KB 的非常小的 xml 文件,我现在必须的实现需要大约 2 秒。是否有任何已知的快速方法可以在 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;

【问题讨论】:

查看***.com/questions/326390/… 取决于您当前读取文件的方式。发布您的代码,以便有人可以帮助您。 我现在没有代码。我稍后会发布它。但在此之前欢迎任何建议:) Panos,我不知道您如何解析 XML 文件,但请尝试在每行添加一个 StringBuffer 对象,而不是添加到一个字符串。 StringBuffer 更快。 请检查我正在使用的代码和建议。我看到我在那里有字符串连接。我会改变的。还有其他建议吗? 【参考方案1】:

最终使用的代码如下:

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;

【讨论】:

在我看来,您的第一个 fn 关闭了它没有打开的流,这似乎不对。换句话说,我认为 getStringFromFile 应该关闭流。 @Tom 实际上这个答案的重要部分是显示循环中发生的事情并创建字符串。无论如何,你是对的,在 getStringFromFile 中关闭流更好,所以我编辑了答案。谢谢。 这不会在字符串末尾添加一个额外的新行吗? @JaredRummler 是的。另外,它会始终将文件的行尾修改为 '\n',这很可能不是您想要的。同样,在 java 中做某事比它需要的更难。 在 Android 中使用Uri 更安全。文件路径可能有效,也可能无效。【参考方案2】:

您可以使用org.apache.commons.io.IOUtils.toString(InputStream is, Charset chs) 来执行此操作。

例如

IOUtils.toString(context.getResources().openRawResource(<your_resource_id>), StandardCharsets.UTF_8)

添加正确的库:

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

dependencies 
    compile 'org.apache.directory.studio:org.apache.commons.io:2.4'

https://***.com/a/33820307/1815624

对于 Maven 存储库,请参阅 -> this link

直接下载jar见->https://commons.apache.org/proper/commons-io/download_io.cgi

【讨论】:

方法已弃用,只是添加了字符集-> public static String toString(InputStream input, Charset encoding) 参见-> commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#toString (java.io.InputStream, java.nio.charset.Charset) 也许现在是,在撰写此答案时它不是。如果您不介意,我可以使用您评论中的信息更新答案。或者你可以自己写答案:) 我不介意,如果我这样做也没关系,恕我直言,您应该像我一样更新答案以使其保持相关性。 我确实写了我自己的答案***.com/a/36701219/181562,其中包含用于获取资产的源...尽管对于给定的问题,我相信您的答案的简洁性使其成为最好的.. . 您能否澄清一下什么是“资源 ID” - 我在 /main 下创建了一个名为 /assets 的目录,并在那里有一个 sampleText.txt 文件。如何将该文件称为输入?请帮忙。【参考方案3】:

重做源自-> the accepted answer的方法集

@JaredRummler 对您的评论的回答:

Read file As String

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

为防止在末尾添加换行符,您可以在第一个循环期间使用布尔值集,就像在代码示例 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;

【讨论】:

这仍然会将行尾修改为 '\n'。似乎没有一个简单的方法。【参考方案4】:

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

val textFile = File(cacheDir, "/text_file.txt")
val allText = textFile.readText()
println(allText)

来自readText() 文档:

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

【讨论】:

他没有使用 Kotlin。问题是针对 Java 的。 @StealthRabbi 在问题中,操作员询问如何在 Java/Android 中执行此操作。当时 Java 是 Android 的主要语言,所以现在发布 Kotlin 版本是有意义的。此外,问题标签仅包括我认为更重要的 Android。 对,他没有使用 Java 标记,因为考虑到问题的年龄,这是假定的。就像我在 1870 年问如何在城市之间快速旅行,而你在 100 年后回答说要坐飞机。 @StealthRabbi 对于 100 年后阅读上述假设性问题的人来说,乘坐飞机是公认的正确答案。 我在 1800 年代写了原始问题。过去我们得到了一些不错的解决方案。但这也是一个很好的可接受的解决方案,因此我们可以看到JVM api和解决方案的演变【参考方案5】:

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

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 = "";
    

【讨论】:

不知道为什么这被否决了。当然,代码很混乱,但这会起作用(如果他用完了为大文件分配缓冲区的内存,那么使用 StringBuffer 的示例也会如此)。它也不会像投票最多的答案那样添加额外的换行符。 numRead 和 length 末尾的比较将字符与字节进行比较。当读取整个文件时,可能会发生这些不相等的情况。 FileReader in = new FileReader(file) 需要 api 级别 19【参考方案6】:
public static String readFileToString(String filePath) 
    InputStream in = Test.class.getResourceAsStream(filePath);//filePath="/com/myproject/Sample.xml"
    try 
        return IOUtils.toString(in, StandardCharsets.UTF_8);
     catch (IOException e) 
        logger.error("Failed to read the xml : ", e);
    
    return null;

【讨论】:

【参考方案7】:

这对我有用

i use this path

String FILENAME_PATH =  "/mnt/sdcard/Download/Version";

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;


【讨论】:

什么是convertStreamToString 悲伤的半复制过去

以上是关于以字符串形式读取文件的主要内容,如果未能解决你的问题,请参考以下文章

以字符串形式读取github上.json文件

Python 读取和输出到txt

c# 将字符串以二进制形式写入文件

以二进制形式读取文件,将其压缩并以二进制形式写回

文件操作流的存储与读取

java读取文件:二进制文件