【问题标题】:Read a file inside a Zip archive and put its content into a String in Android读取 Zip 存档中的文件并将其内容放入 Android 中的字符串
【发布时间】:2019-11-19 05:42:17
【问题描述】:

这是我的第一个问题,尽管我已经使用了 Stack Overflow 的许多技巧。但是对于这种情况,我还没有找到解决方案。

情况如下:我有一个压缩文件,我想读取一个特定文件并将其内容放入一个字符串变量中,该变量将被返回并放入 Android 中的 TextView 中。我不想将文件写入sdcard,我只想执行内存操作。

例如,在 db.zip 中,我有一个名为 packed.txt 的文件,其内容是“Stack á é ç”。我的方法中返回的字符串显示“83 116 97 99 107 32 195 161 32 (...)”,这是字符的 UTF-8 值。到目前为止,我尝试将它们转换为人类可读的形式,但没有成功。尝试过 InputStreamReader 但我无法正确使用它。我的源代码如下。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import android.util.Log;

/** 
 * 
 * @author jon 
 */ 
public class Decompress { 
  private String _zipFile; 
  private String _location;

  public Decompress(String zipFile, String location) { 
    _zipFile = zipFile; 
    _location = location; 

    _dirChecker(""); 
  } 

  public String unzip(String desiredFile) { 

      String strUnzipped = ""; 

      try  { 
      FileInputStream fin = new FileInputStream(_zipFile); 
      ZipInputStream zin = new ZipInputStream(fin); 
      ZipEntry ze = null; 
      while ((ze = zin.getNextEntry()) != null) { 
        Log.v("Decompress", "Unzipping " + ze.getName()); 

        if(ze.isDirectory()) { 
          _dirChecker(ze.getName()); 
        } else { 

          //FileOutputStream fout = new FileOutputStream(_location + ze.getName());

            /**** Changes made below ****/  
              if (ze.getName().toString().equals(desiredFile)) {                  
                byte[] bytes = new byte[(int) ze.getSize()];
            if (zin.read(bytes, 0, bytes.length) == bytes.length) {
              strUnzipped = new String(bytes, "UTF-8");
            }
            else {
              strUnzipped = "Read error...";
            }

            /*** REMOVED
            if (ze.getName() == desiredFile) {
            for (int c = zin.read(); c != -1; c = zin.read()) {
              strUnzipped += c;
              //fout.write(c); 
            } */
          }

          zin.closeEntry(); 
          //fout.close(); 
        } 

      } 
      zin.close(); 
    } catch(Exception e) { 
      Log.e("Decompress", "unzip", e); 
    }

    return strUnzipped;

  } 

  private void _dirChecker(String dir) { 
    File f = new File(_location + dir); 

    if(!f.isDirectory()) { 
      f.mkdirs(); 
    } 
  } 
}

【问题讨论】:

    标签: java android unzip


    【解决方案1】:

    对不起,我最初发布了这个....跑过你的段落,说你已经尝试过了。

    您可以使用“UTF-8”字符集创建 InputStreamReader,它会自动为您将输入数据转换为正确的字符。

    while ((ze = zin.getNextEntry()) != null) { 
        Log.v("Decompress", "Unzipping " + ze.getName()); 
        if(ze.isDirectory()) { 
            _dirChecker(ze.getName()); 
        } else {
            if (ze.getName() == desiredFile) {
                byte[] bytes= new byte[ze.getSize()];
                zin.read(bytes, 0, bytes.length);
                strUnzipped= new String( bytes, "UTF-8" );
                /* Removing this as it is easier to just read all the bytes in at once
                InputStreamReader isr= new InputStreamReader(zin, "UTF-8");
                char c= 0;
                for (char c = isr.read(); c != -1; c = isr.read()) {
                strUnzipped += c;
                } 
                */
            }
            zin.closeEntry(); 
        }
    } 
    

    请尝试以上方法,看看效果如何。

    【讨论】:

    • 嗨,戴夫,感谢您的回答。我试过了,Eclipse 说“无法从 int 转换为 char”,它建议进行以下更正:“for (char c = (char) isr.read(); c != -1; c = (char) isr.read ()) {"。但是编译后会导致模拟器崩溃!
    • 对不起,我忘记了读取返回一个“int”。至于坠机,那真的很奇怪!我会尝试清理您的项目(Projects > Clean)代码库并重新启动模拟器,然后将您的应用程序重新部署到模拟器。如果这仍然给您带来问题,请再次给我留言。
    • 实际上我认为我看到了我建议的读取循环的问题。给我一分钟时间找出正确的方法。
    • 我对循环进行了更改,基本上将其删除。但这应该会更好。作为健全性检查,您可能需要调整 zin.read() 行以检查以确保您已读取正确数量的字节。
    • 成功了!感谢您的帮助。尽管我需要在行中添加一个“(int)”:byte [] bytes = new byte [(int)ze.getSize()];。那安全吗?我在上面添加了一个健全性检查,这是你的意思吗?
    【解决方案2】:

    为什么不将它们加载到字节数组中并使用 new String(byte[]) 或使用 StringBuilder?

    StringBuilder sb = new StringBuilder();
    for (int c = zin.read(); c != -1; c = zin.read()) {
        sb.append((byte)c);
    }
    ...
    return sb.toString();
    

    【讨论】:

    • 感谢您的回答。结果字符串再次显示 UTF-8 值。如何将整数变量“c”加载到字节数组中? Valeu conterrâneo!
    • 对不起,把 (byte) 换成 (char),这是一个错字:(
    【解决方案3】:
    ...         
    while ((ze = zis.getNextEntry()) != null) {
        if (ze.getName().equalsIgnoreCase(desiredFile)) {
            byte[] buffer = new byte[1024];
            String texto="";
            while (zis.read(buffer) > 0) {
                texto+=new String(buffer,"ISO-8859-1");
            }   
            break;
        }
    }
    

    返回文本;

    【讨论】:

    • 您能否提供一些额外的细节,上面的 sn-p 如何帮助解决问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 2018-12-12
    相关资源
    最近更新 更多