Массив байтов, записанный в файл изолированной области хранения в приложении C# для Windows Phone 7, недействителен

У меня есть приложение С# для Windows Phone 7.1, которое загружает PDF-файл с внешнего веб-сервера, а затем (пытается) сохранить его в изолированном хранилище в виде файла. Я пробовал несколько разных способов сделать это, но файл всегда оказывается примерно на 30% больше, и когда я открываю его в текстовом редакторе, вместо того, чтобы видеть ОБЫЧНЫЕ символы «PDF» в начале файла, за которыми следует закодированные символы я вижу в основном барахлом. Используемый мной тестовый файл должен иметь размер 161 КБ, но когда я просматриваю файл с помощью обозревателя изолированных хранилищ, это 271к.

Сначала я загружаю файл в строку. Я проверил строку в этот момент в отладчике, и она содержит правильные значения и правильную длину. Проблема возникает, когда я пытаюсь записать его в изолированное хранилище. Я пробовал оба StreamWriter и BinaryWriter с одинаковыми неверными результатами. Содержимое результирующего файла выглядит как длинный поток ненужных символов. Обратите внимание, я удаляю файл, если он существует, на всякий случай, прежде чем записывать содержимое. Ниже приведен мой код, использующий версию BinaryWriter. Что не так?

async public static Task URLToFileAsync(
                                string strUrl, 
                                string strDestFilename, 
                                IProgress<int> progress, 
                                CancellationToken cancelToken)
{
    strUrl = strUrl.Trim();

    if (String.IsNullOrWhiteSpace(strUrl))
        throw new ArgumentException("(Misc::URLToFileAsync) The URL is empty.");

    strDestFilename = strDestFilename.Trim();

    if (String.IsNullOrWhiteSpace(strDestFilename))
        throw new ArgumentException("(Misc::URLToFileAsync) The destination file name is empty.");

    // Create the isolated storage file.
    // FileStream fs = Misc.CreateIsolatedStorageFileStream(strDestFilename);
    IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();

    // Delete the file first.
    if (isoStorage.FileExists(strDestFilename))
        isoStorage.DeleteFile(strDestFilename);

    IsolatedStorageFileStream theIsoStream = isoStorage.OpenFile(strDestFilename, FileMode.Create);

    FileStream fs = theIsoStream;

    // If the stream writer is NULL, then the file could not be created.
    if (fs == null)
        throw new System.IO.IOException("(Misc::URLToFileAsync) Error creating or writing to the file named: " + strDestFilename);

    BinaryWriter bw = new BinaryWriter(fs);

    try
    {

        // Call URLToStringAsync() to get the web file as a string first.
        string strFileContents = await URLToStringAsync(strUrl, progress, cancelToken);

        // >>>> NOTE: strFileContents looks correct and is the correct size.

        // Operation cancelled?
        if (!safeCancellationCheck(cancelToken))
        {
            // Note.  BinaryWriter does not have an Async method so we take the hit here
            //  to do a synchronous operation.
            //  See this Stack Overflow post.
            // http://stackoverflow.com/questions/10315316/asynchronous-binaryreader-and-binarywriter-in-net

            // >>>> NOTE: strFileContents.ToCharArray() looks correct and is the correct length.
            bw.Write(strFileContents.ToCharArray(), 0, strFileContents.Length);
        } // if (safeCancellationCheck(cancelToken))
    }
    finally
    {
        // Make sure the file is cleaned up.
        bw.Flush();
        bw.Close();

        // Make sure the file is disposed.
        bw.Dispose();
    } // try/finally

    // >>>> NOTE: output file in Isolated Storage Explorer is the wrong size and contains apparently junk.
} // async public static void URLToFileAsync

person Robert Oschler    schedule 09.04.2013    source источник


Ответы (1)


Вы не можете загрузить двоичный файл в строку. Результат будет неверным, как вы уже выяснили.

См. этот ответ, в котором показано, как загрузить двоичный файл в изолированное хранилище: https://stackoverflow.com/a/6909201/1822514< /а>

person chue x    schedule 09.04.2013
comment
@chue_x. Спасибо. Это сработало, но я хотел бы знать, почему, тем более что длина строки идентична размеру веб-файла. Единственная причина разницы, о которой я могу думать, заключается в том, что C#/.NET хранит строки с многобайтовой кодировкой или какой-либо другой кодировкой в ​​самой памяти строк, чего не делают по крайней мере не-.NET C, C++ и Delphi. . - person Robert Oschler; 09.04.2013
comment
@RobertOschler Все строки в .NET кодируются в UTF-16. Поэтому при чтении строки среда выполнения попытается преобразовать символы в эту кодировку. Если невозможно узнать, какую кодировку использовал источник, по умолчанию используется UTF-8. Таким образом, в вашем случае .NET подумал, что ваш PDF-файл представляет собой текст в кодировке UTF-8, и преобразовал его в UTF-16. Поскольку обе кодировки не имеют одинакового двоичного представления, это объясняет, почему ваши данные были повреждены. - person Kevin Gosse; 09.04.2013
comment
@KooKiz - это объясняет, спасибо. Я переключил все на байтовые массивы, и теперь все хорошо. - person Robert Oschler; 09.04.2013