Проблема загрузки папки Dropbox (C#)

Я автоматически загружаю целую папку из своего хранилища Dropbox (?) Через веб-ссылку, например:https://www.dropbox.com/sh/bunchOfLetters/somthnsomthn?dl=1 только с базовым веб-клиентом:

using (WebClient wc = new WebClient())
{
     wc.DownloadFile(new Uri(uri), _basePath + localPath);
}

Папка, естественно, поставляется в виде файла.rar (из-за системы загрузки Dropbox), и если я пытаюсь открыть файл вручную (через Winrar), проблем нет вообще. Теперь возникает проблема.... если я пытаюсь использовать какой-либо вид автоматической библиотеки (например, unrar или SharpCompress), она всегда дает моему "Corupted Header", как если бы загрузка не получилась бы все или файл просто сломался... но все равно открытие его с помощью Winrar работает просто отлично.

Если у кого-то есть идеи, как и почему; Я был бы рад услышать ваши мысли.

Редактировать:

вот функция, которую я использую для SharpCompress:

public static bool ExtractToFolder(string extractionPackage, string outputPath)
        {
            if (extractionPackage == null) throw new ArgumentNullException(nameof(extractionPackage));
            if (outputPath == null) throw new ArgumentNullException(nameof(outputPath));
            if (string.IsNullOrEmpty(extractionPackage))
                throw new ArgumentException("Argument is null or empty", nameof(extractionPackage));
            if (string.IsNullOrEmpty(outputPath))
                throw new ArgumentException("Argument is null or empty", nameof(outputPath));
            if (!extractionPackage.EndsWith(".rar")) throw new InvalidDataException("not a .rar File");
            Directory.CreateDirectory(outputPath);

            try
            {
                using (Stream stream = File.OpenRead(extractionPackage))
                using (RarReader reader = RarReader.Open(stream))
                {
                    while (reader.MoveToNextEntry())
                    {
                        reader.WriteEntryToDirectory(outputPath, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite);
                    }
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

и если кто-то заинтересован в unrar один: .. Я знаю, что это не очень хорошо сделано, но он по-прежнему работает для обычных файлов... только не Dropbox

namespace Cryptus.Rar
{
/// <summary>
/// just for compatibility purposes, use <see cref="SharpCompress"/>
/// </summary>
public class Unrar
{
    public enum RarOperations
    {
        OP_EXTRACT = 0,
        OP_TEST = 1,
        OP_LIST = 2
    }

    public const int ERAR_END_ARCHIVE = 10;
    public const int ERAR_NO_MEMORY = 11;
    public const int ERAR_BAD_DATA = 12;
    public const int ERAR_BAD_ARCHIVE = 13;
    public const int ERAR_UNKNOWN_FORMAT = 14;
    public const int ERAR_EOPEN = 15;
    public const int ERAR_ECREATE = 16;
    public const int ERAR_ECLOSE = 17;
    public const int ERAR_EREAD = 18;
    public const int ERAR_EWRITE = 19;
    public const int ERAR_SMALL_BUF = 20;

    public const int RAR_OM_LIST = 0;
    public const int RAR_OM_EXTRACT = 1;

    public const int RAR_SKIP = 0;
    public const int RAR_TEST = 1;
    public const int RAR_EXTRACT = 2;

    public const int RAR_VOL_ASK = 0;
    public const int RAR_VOL_NOTIFY = 1;

    [DllImport("unrar.dll")]
    public static extern IntPtr RAROpenArchive(ref RAROpenArchiveData ArchiveData);

    [DllImport("unrar.dll")]
    public static extern int RARCloseArchive(IntPtr hArcData);

    [DllImport("unrar.dll")]
    public static extern int RARReadHeader(IntPtr hArcData, ref RARHeaderData HeaderData);

    [DllImport("unrar.dll")]
    public static extern IntPtr RAROpenArchiveEx(ref RAROpenArchiveDataEx ArchiveData);

    [DllImport("unrar.dll")]
    public static extern int RARReadHeaderEx(IntPtr hArcData, ref RARHeaderDataEx HeaderData);

    [DllImport("unrar.dll")]
    public static extern int RARProcessFile(IntPtr hArcData, int Operation, string DestPath, string DestName);

    [DllImport("unrar.dll")]
    public static extern int RARGetDllVersion();

    [DllImport("user32.dll")]
    private static extern bool CharToOem(string lpszSrc, [Out] StringBuilder lpszDst);

    /// <summary>
    ///     opens an arcive and unloads its content to destDolder
    /// </summary>
    /// <param name="strFileName">input .rar File</param>
    /// <param name="destFolder">destination Folder</param>
    public void UnloadArchieve(string strFileName, string destFolder)
    {
        IntPtr lHandle;
        int iStatus;
        RAROpenArchiveData uRAR = new RAROpenArchiveData();
        RARHeaderData uHeader = new RARHeaderData();

        uRAR.ArcName = strFileName + char.MinValue;
        uRAR.OpenMode = RAR_OM_EXTRACT;
        uRAR.CmtBuf = null;

        string ExtractDir = Path.GetDirectoryName(strFileName);
        StringBuilder sbDir = new StringBuilder();
        CharToOem(destFolder, sbDir);

        lHandle = RAROpenArchive(ref uRAR);
        if (uRAR.OpenResult != 0)
            Console.Write("Unable to open the Archieve!!!");
        while (RARReadHeader(lHandle, ref uHeader) == 0)
        {
            int result = RARProcessFile(lHandle, 2, sbDir.ToString(), null);
            if (0 != result)
                Console.Write("Unable to open the Archieve!!!");
        }


        iStatus = RARCloseArchive(lHandle);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RARHeaderData
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string ArcName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string FileName;
        public uint Flags;
        public uint PackSize;
        public uint UnpSize;
        public uint HostOS;
        public uint FileCRC;
        public uint FileTime;
        public uint UnpVer;
        public uint Method;
        public uint FileAttr;
        public string CmtBuf;
        public uint CmtBufSize;
        public uint CmtSize;
        public uint CmtState;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RAROpenArchiveData
    {
        public string ArcName;
        public uint OpenMode;
        public uint OpenResult;
        public string CmtBuf;
        public uint CmtBufSize;
        public uint CmtSize;
        public uint CmtState;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RAROpenArchiveDataEx
    {
        public string ArcName;
        public string ArcNameW;
        public uint OpenMode;
        public uint OpenResult;
        public string CmtBuf;
        public uint CmtBufSize;
        public uint CmtSize;
        public uint CmtState;
        public uint Flags;
        public uint Reserved;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RARHeaderDataEx
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string ArcName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string FileName;
        public string FileNameW;
        public uint Flags;
        public uint PackSize;
        public uint PackSizeHigh;
        public uint UnpSize;
        public uint UnpSizeHigh;
        public uint HostOS;
        public uint FileCRC;
        public uint FileTime;
        public uint UnpVer;
        public uint Method;
        public uint FileAttr;
        public string CmtBuf;
        public uint CmtBufSize;
        public uint CmtSize;
        public uint CmtState;
        public uint Reserved;
    }
}

1 ответ

Решение

Итак, похоже, что @smarx был прав с его комментарием! Это немного странно, но Dropbox генерирует файлы.rar, которые содержат не rar, а zip-заголовок. Это не проблема для любой формы автоматического определения формата заголовка, но если вы используете метод извлечения rar (который следует использовать для файлов.rar..), он не будет работать.

Другие вопросы по тегам