【问题标题】:How to extract tar.gz including multi byte characters and prohibited characters on windows如何在 Windows 上提取包含多字节字符和禁止字符的 tar.gz
【发布时间】:2014-10-30 14:59:56
【问题描述】:

我尝试使用以下库提取 tar.gz,但它们都不能完美运行。
我创建tar.gz的环境是linux,解压的环境是windows。
而且我无法触摸linux服务器,因为服务器是其他公司的。

M:多字节字符
W: Windows 禁止字符(: ; / \(¥)| , * ?" < >)

SharpZiplib (C#)
男:不合格
W:可以将禁用字符替换为其他字符

                Stream st = new GZipInputStream(File.OpenRead(attFile));
                TarArchive archive = TarArchive.CreateInputTarArchive(st, TarBuffer.DefaultBlockFactor);
                archive.SetKeepOldFiles(false);
                archive.AsciiTranslate = false;
                archive.SetUserInfo(0, "", 0, "None");
                Directory.CreateDirectory(Work);
                archive.ExtractContents(Work);
                archive.Close();

tar32.dll (C#)
男:好的
W:未生成数据

    public static void ExtractTarWithDLL(string Targzpath)
    {
        IntPtr i = new IntPtr();
        string szCmdLine = "-x " + Targzpath + " -o " + Path.GetDirectoryName(Targzpath);
        Console.WriteLine(Path.GetDirectoryName(Targzpath));
        StringBuilder error = new StringBuilder(512);

        Tar(i, szCmdLine, error, 512);
    }

tar-cs (C#)
男:不合格
W:可以将禁用字符替换为其他字符

    /// <summary>
    /// Example of tar-cs library usage to extract tar.gz-archives.
    /// Please use the latest version (from trunk) of the library.
    /// </summary>
    public static class TarGZip
    {
        public static void Extract(string inputFile, string outputDirectory)
        {
            using (FileStream inputStream = File.OpenRead(inputFile))
            using (Stream tarStream = UnGZipSteam(inputStream))
            {
                var tarReader = new TarReader(tarStream);
                while (tarReader.MoveNext(false)) // Moves pointer to the next file in the tar archive.
                {
                    ExtractTarEntry(tarReader, outputDirectory);
                }
            }
        }

        /// <summary>
        /// Since GZipStream.Position Property is not implemented,
        /// it is necessary to use MemoryStream as intermediate storage.
        /// </summary>
        /// <param name="inputStream">The input stream.</param>
        /// <returns>Un-gzipped stream.</returns>
        private static Stream UnGZipSteam(Stream inputStream)
        {
            using (GZipStream gZipStream = new GZipStream(inputStream, CompressionMode.Decompress))
            {
                MemoryStream memoryStream = new MemoryStream();
                gZipStream.CopyTo(memoryStream);
                memoryStream.Position = 0;
                return memoryStream;
            }
        }

        private static void ExtractTarEntry(TarReader tarReader, string outputDirectory)
        {
            string relativePath = tarReader.FileInfo.FileName;

            // Relative path can contain slash, not backslash.
            // Use Path.GetFullPath() method to convert path.
            //relativePath = relativePath.Replace('?','');
            string fullPath = Path.GetFullPath(Path.Combine(outputDirectory, relativePath));
            //string fullPath = Path.GetFullPath(Path.Combine(outputDirectory, "windows.txt"));

            switch (tarReader.FileInfo.EntryType)
            {
                case EntryType.File:
                case EntryType.FileObsolete:
                    using (FileStream outputStream = File.Create(fullPath))
                    {
                        // Read data from a current file to a Stream.
                        tarReader.Read(outputStream);
                    }
                    break;
                case EntryType.Directory:
                    Directory.CreateDirectory(fullPath);
                    break;
                default:
                    throw new NotSupportedException("Not supported entry type: " + tarReader.FileInfo.EntryType);
            }
        }
    }

tarlib (C++)
M:数据未生成
W:未生成数据
我正在使用这个示例代码。 http://www.codeproject.com/Articles/470999/tarlib-Windows-TAR-Library

ant.jar (java)
M:默认情况下,多字节字符被替换为'_'
W:抛出 java.io.FileNotFoundException

public class Targz {

public void extract(Path path) throws IOException {


    if(!path.toString().endsWith(".tar.gz")){
        throw new Error("extension must be tar.gz.");
    }

    TarInputStream tin = new TarInputStream(new GZIPInputStream(new FileInputStream(path.toFile())));

    for(TarEntry tarEnt = tin.getNextEntry(); tarEnt != null; tarEnt = tin.getNextEntry()) {
        if(tarEnt.isDirectory()){
            new File(tarEnt.getName()).mkdir();
        }
        else {
            FileOutputStream fos = new FileOutputStream(new File(tarEnt.getName()));
            tin.copyEntryContents(fos);
        }
    }
    tin.close();
} 

}

有人可以帮帮我吗?谢谢。

【问题讨论】:

  • 谁能解释为什么这应该是题外话? OP 已经尝试了不同的框架/库,但没有成功。所以我们可以用另一个库或配置来回答已经尝试过的解决问题的方法。这似乎是我的话题。
  • 有很多东西,不适用于符号链接之类的窗口或许多子文件夹。你不必使用linux服务器,只要是任何linux系统
  • 对于 JaMaBing 的评论,这里有一些获取 Linux 系统的方法: (A) 下载 Linux Live CD 并在计算机上启动它而不安装它。 (B) 在 Amazon EC2、Digitalocean、Nitrous.io 或类似服务的网络上按小时租用 Linux VPS。通常不到 1 美元/小时。 (C) 使用 VirtualBox 或 VMWare 在 Windows 中安装 Linux 虚拟机。在所有情况下,您需要做的就是将您的 .tar.gz 文件复制到那里,展开,浏览它,得到您需要的东西。 更改坏名,用 zip 或其他任何方式压缩它以实现 Windows 兼容性。完成后删除linux的东西。
  • @ebyhr 请看一下这个要点gist.github.com/SubOptimal/acd3059a0fde04157b6b。多字节字符不是问题。保留字符需要在创建目录/文件之前进行清理。
  • @SubOptimal 我确认文件可以完美提取!非常感谢!!!!!!

标签: java c# c++ windows tar


【解决方案1】:

试图提取 tar.gz 以下库,但它们都不能正常工作。创建tar.gz的环境是linux,解压的环境是windows。而且我无法触摸linux服务器,因为服务器是其他公司的。

嗨, 你试过http://www.7-zip.org/ 吗?

【讨论】:

  • 感谢您的快速回复!我试过 7-zip,但是多字节字符变成了垃圾。
猜你喜欢
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
相关资源
最近更新 更多