Присоединение бинарных файлов, которые были разделены через загрузку - PullRequest
1 голос
/ 02 февраля 2009

Я пытаюсь объединить несколько двоичных файлов, которые были разбиты во время загрузки. Требование вытекает из проекта http://asproxy.sourceforge.net/.. В этом проекте автор позволяет загружать файлы, предоставляя URL.

Проблема возникает из-за того, что моему серверу не хватает памяти для хранения файла размером более 20 мегабайт. Чтобы решить эту проблему, я изменил код, чтобы не загружать файлы размером более 10 мегабайт, если файл больше, то позволит пользователю загрузить первые 10 мегабайт. Затем пользователь должен продолжить загрузку и, надеюсь, получить вторые 10 мегабайт. Теперь у меня все это работает, за исключением случаев, когда пользователю нужно присоединиться к загруженным им файлам, и я получаю поврежденные файлы, насколько я могу судить, что что-то добавляется или удаляется через загрузку.

В настоящее время я объединяю файлы, читая все файлы и записывая их в один файл. Это должно работать, поскольку я читаю и пишу в байтах. Код, который я использовал для присоединения к файлам, указан здесь http://www.geekpedia.com/tutorial201_Splitting-and-joining-files-using-C.html

У меня нет точного кода при себе, как только я дома, я опубликую точный код, если кто-нибудь захочет помочь.

Пожалуйста, дайте мне знать, если я что-то упустил или есть лучший способ сделать это, т.е. что я мог бы использовать в качестве альтернативы потоку памяти. Исходный код исходного проекта, в который я внес изменения, можно найти здесь http://asproxy.sourceforge.net/download.html, следует отметить, что я использую версию 5.0. Файл, который я изменил, называется WebDataCore.cs, и я изменил строку 606 так, чтобы только до 10 мегабайт данных было загружено для продолжения выполнения.

Дайте мне знать, если я что-то пропустил.

Спасибо

Ответы [ 3 ]

3 голосов
/ 02 февраля 2009

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

Самый простой способ загрузить файл - это просто:

using(WebClient client = new WebClient()) {
    client.DownloadFile(remoteUrl, localPath);
}

Повторный код разделения / соединения - опять проблема в том, что вы буферизуете все в памяти; File.ReadAllBytes это плохо, если вы не знаете, что у вас есть небольшие файлы. То, что вы должны иметь, это что-то вроде:

byte[] buffer = new byte[8192]; // why not...
int read;
while((read = inStream.Read(buffer, 0, buffer.Length)) > 0)
{
    outStream.Write(buffer, 0, read);
}

Используется умеренный буфер для передачи данных между двумя потоками. Гораздо эффективнее. Цикл говорит:

  • попытаться прочитать некоторые данные (не более, размер буфера)
  • (это будет считывать как минимум 1 байт, или мы достигли конца потока)
  • если мы что-то читаем, записываем это множество байтов из буфера в вывод
2 голосов
/ 11 марта 2009

В конце концов я обнаружил, что с помощью запроса FTP я смог обойти проблему с памятью и файл был сохранен правильно.

Спасибо за помощь

1 голос
/ 02 февраля 2009

Этот пример загружает каждый блок в память, вместо этого вы можете сделать что-то вроде этого:

int bufSize = 1024 * 32;
byte[] buffer = new byte[bufSize];

using (FileStream outputFile = new FileStream(OutputFileName, FileMode.OpenOrCreate,
FileAccess.Write, FileShare.None, bufSize))
{
    foreach (string inputFileName in inputFiles)
    {
        using (FileStream inputFile = new FileStream(inputFileName, FileMode.Append,
            FileAccess.Write, FileShare.None, buffer.Length))
    {
    int bytesRead = 0;

    while ((bytesRead = inputFile.Read(buffer, 0, buffer.Length)) != 0)
    {
        outputFile.Write(buffer, 0, bytesRead);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...