【问题标题】:Read the content of CSV files inside a tar.gz archive读取 tar.gz 存档中 CSV 文件的内容
【发布时间】:2019-04-01 13:45:15
【问题描述】:

我想将 tar.gz 存档的内容保存在数据库表中。

存档包含 CSV 格式的 txt 文件。

这个想法是为 txt 文件中的每一行在数据库中插入一个新行。

问题是我不能单独读取一个文件的内容然后继续下一个文件。

EntryTableEntryTableLine 下面是 Hibernate 实体。

EntryTableEntryTableLine 处于 OneToMany 关系(一个文件 -EntryTable- 可以有很多行 -EntryTableLine-)。

public static final int TAB = 9;

FileInputStream fileInputStream = new FileInputStream(fileLocation);
GZIPInputStream gzipInputStream = new GZIPInputStream(fileInputStream);
TarArchiveInputStream tar = new TarArchiveInputStream(gzipInputStream);

BufferedReader reader = new BufferedReader(new InputStreamReader(tar));
// Columns are delimited with TAB
CSVFormat csvFormat = CSVFormat.TDF.withHeader().withDelimeter((char) TAB);
CSVParser parser = new CSVParser(reader, csvFormat);

TarArchiveEntry tarEntry = tar.getNextTarEntry();

while(tarEntry != null){
  EntryTable entryTable = new EntryTable();
  entryTable.setFilename(tarEntry.getName());

  if(reader != null){

     // Here is the problem
     for(CSVRecord record : parser){
        //this could have been a StringBuffer
        String line;
        int i = 1;
        for(String val : record){
           line = "<column" + i + ">" + val + "</column" + i + ">";
        }

        EntryTableLine entryTableLine = new EntryTableLine();
        entryTableLine.setContent(line);
        entryDao.saveLine(entryTableLine);
      }
  }
  tarEntry = tar.getNextTarEntry();
}

我尝试将 tarEntry.getFile() 转换为 InputStream,但不幸的是 tarEntry.getFile() 为空。

假设我在存档中有 4 个文件。每个文件里面有 3 行。但是,在数据库中,有些条目有 5 行,而有些则没有。

谢谢!

【问题讨论】:

  • 我相信您需要在每次调用 getNextTarEntry 后从 TarArchiveInputStream 中读取数据。
  • 正如TarArchiveEntry.getFile() 的文档所述:“此方法仅适用于从文件创建的条目,但不适用于从存档读取的条目。”。文档的示例页面包含一些代码how to read a TAR archive
  • 我没有正确读取 InputStream。在执行类似于示例“如何读取 TAR 存档”的操作后,我设法读取了每个文件的内容。谢谢:D

标签: java hibernate apache-commons-compress


【解决方案1】:

你可以使用Apache Commons CompressTarArchiveInputStream如下图(Reference):

TarArchiveInputStream input = new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream("C:\\Users\\User\\Desktop\\Books\\test\\CoverLetter-Version2.gz")));
TarArchiveEntry entry = input.getNextTarEntry();
System.out.println(entry.getName()); // prints the name of file inside the tar
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
while (entry != null) {
    br = new BufferedReader(new InputStreamReader(input)); // Read directly from tarInput
    System.out.println("For File = " + currentEntry.getName());
    String line;
    while ((line = br.readLine()) != null) {
          System.out.println("line="+line);
    }
     entry = input.getNextTarEntry(); 
}

【讨论】:

    【解决方案2】:

    尝试直接从输入流中读取:

            BufferedReader br = null;
            while(tarEntry != null){
                br = new BufferedReader(new InputStreamReader(tarEntry));
    

    【讨论】:

    • InputStreamReader 需要一个 InputStream,但 tarEntry 不是而且 InputStream
    【解决方案3】:

    做类似的事情解决了这个问题:

    TarArchiveEntry entry = tarInput.getNextTarEntry();
    byte[] content = new byte[entry.getSize()];
    LOOP UNTIL entry.getSize() HAS BEEN READ {
        tarInput.read(content, offset, content.length - offset);
    }
    

    Reference mentioned in the comments

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      • 2021-12-25
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 2014-11-28
      相关资源
      最近更新 更多