Подтвердить что ты не робот

FileStream to Byte []: Windows XP vs Windows 8

Недавно мне пришлось написать код, который:

  • Пользовательский интерфейс принимает файл (изображение)
  • Преобразует в `byte []
  • Загружает byte[] на сайт (используя HttpWebRequest. ContentType is multipart/form-data)
  • Затем веб-сайт считывает поток, использует параметры, которые я отправил вместе с файлом, сохраняет byte[] в базе данных.

Это изображение затем используется в отчетах, и пользователь может загружать изображение всякий раз. И это отлично работало, пока мы не начали его тестировать на машине с Windows XP. Всякий раз, когда я загружаю любое изображение с ПК XP, изображение не будет отображаться. После некоторой отладки и тестирования и записи этого multipart/form-data в текстовый файл я увидел, что byte[] файла отличается от Windows XP и Windows 8 (или даже 7). Сгенерированный размер файла также отличался.

Я использую VS2012 с .Net 4.0 и установил (и снова отремонтировал).Net 4 на ПК XP. Я могу только думать, что либо две операционные системы кодируют по-разному, либо, возможно, свою разницу между 32-битной ОС и 64-разрядной. Очевидно, я понятия не имею, что не так, и даже не знаю, с чего начать. Я хотел бы знать, может ли кто-нибудь указать мне в правильном направлении?

Вот код UI-стороны:

//Wrapped around each parameter. The last boundary after the byte[] file >has been omitted.
string boundary = "----------------------------" + >DateTime.Now.Ticks.ToString("x");

//Creating the httpWebRequest as multipart with "POST" method.
httpWebRequest = (HttpWebRequest)WebRequest.Create(_webUploadUrl);
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = true;
httpWebRequest.Credentials = >System.Net.CredentialCache.DefaultCredentials;

//Upload stream will be built with all the parameters, followed by the >byte[] file.
Stream uploadStream = new System.IO.MemoryStream();


byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes(boundary + >"\r\n");


string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

//Parameters:
//Foreach parameter, Wrap in boundary
foreach (string key in _nvcParameters.Keys)
{
    string formitem = string.Format(formdataTemplate, key, >_nvcParameters[key]);
    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
    uploadStream.Write(formitembytes, 0, formitembytes.Length);
}

byte[] netBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--");
uploadStream.Write(netBytes, 0, netBytes.Length);

//The actual file:           
uploadStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; >filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
string header = string.Format(headerTemplate, "uplTheFile", _fileName);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
uploadStream.Write(headerbytes, 0, headerbytes.Length);

//While file is greater than buffer, write to uploadStream.
byte[] buffer = new byte[1024];
int bytesRead = 0;
long fileSize = pFileStream.Length;            
long uploadedValue = 0;

while ((bytesRead = (pFileStream).Read(buffer, 0, buffer.Length)) != 0)
{
    uploadStream.Write(buffer, 0, bytesRead);
    Application.DoEvents();
}
httpWebRequest.ContentLength = uploadStream.Length;
//Close the original fileStream.
pFileStream.Close();

Веб-сайт использует UTF8. Я могу опубликовать его, если это необходимо, но поскольку параметр byte[] отличается, я думал, что проблема может быть там.


@Ramhound Использование длинных? вы имеете в виду переменные fileSize и uploadedValue? Код является частью UI-стороны системы, очень большой, и я только начинаю разбираться в некоторых частях, так или иначе, я проверял свойства Project (если это подходящее место для проверки). На этапе сборки целью платформы является x86. Вы говорите об этом или о чем-то еще? Извините, я все еще студент и новичок в С# (и vs, если на то пошло)

Я открыл оба файла на машине Windows 8. Размер файла win8 равен 6kb и содержит больше символов.

Вот первые несколько строк массива. _ncvParameters совпадают (как и загруженный файл). Вот первая часть результирующей многочастной формы (ncvParameters, за которой следуют первые несколько строк файла byte[]):

Win8:

------------------------------ 8d00a632401f30e Content-Disposition: form-data; name= "о";

25 ------------------------------ 8d00a632401f30e Content-Disposition: данные формы; name= "к";

2913 ------------------------------ 8d00a632401f30e Content-Disposition: данные формы; name= "и"

255 ------------------------------ 8d00a632401f30e Content-Disposition: данные формы; name= "е";

Синий hills.jpg ------------------------------ 8d00a632401f30e Content-Disposition: данные формы; name= "м";

изображение/JPEG ------------------------------ 8d00a632401f30e Content-Disposition: данные формы; name= "uplTheFile"; filename = "Blue hills.jpg" Content-Type: Применение/октет-поток

‰ PNG

IHDR  €  à   5ÑÜä   sRGB ®Îé   gAMA  ±üa      pHYs  à  ÃÇo¨d  ÿ¥IDATx^ìýg—\7²­ëÿ÷¾gïî–§÷¤H9Š¢DR"—Ú{Ç6²"÷M‘yç¹V$™UÅ–úô>÷|˜@

~ÌÄ2y ×? OݾøáíÛWþ ± OY † [ж € "õøû-pëÊßnï㺠· Ao ‡ uxK¾í

WinXP:

------------------------------ 8d00a639ff7bf76 Content-Disposition: form-data; name= "о";

25 ------------------------------ 8d00a639ff7bf76 Content-Disposition: данные формы; name= "к";

2913 ------------------------------ 8d00a639ff7bf76 Content-Disposition: данные формы; name= "и"

255 ------------------------------ 8d00a639ff7bf76 Content-Disposition: данные формы; name= "е";

Синий hills.jpg ------------------------------ 8d00a639ff7bf76 Content-Disposition: данные формы; name= "м";

изображение/JPEG ------------------------------ 8d00a639ff7bf76 Content-Disposition: данные формы; name= "uplTheFile"; filename = "Blue hills.jpg" Content-Type: Применение/октет-поток

‰ PNG

IHDR         ĉ   sRGB ®Îé   gAMA  ±üa    cHRM  z&  €„  ú   €è  u0  ê`  :˜  pœºQ<   IDATWc`    ªÕÈQ   

IEND®B`,èÊû: uÊžòÞ ° E [=) Qä¡w ¢% º2§Î ~ O ™ ‰ ¬½ × F ± ¤ ~ ¯ × 1 ‰ H $01 # ùßÿâ <ÿ¯¿¸äÿý ‡ <-u;? üX§¿8 (уо $º $à ": яюA © ÚêÀBTÿpà% • ~ ÖbºËá þÝü8ùŸ: å_ø (IÿGã <þâ/Æ Cô¨Í. * > QV


@Xaqron - uploadStream - это memoryStream. Вся многочастная форма записывается в этот поток, который затем записывается в byte[]. Которое передается в HttpWebRequest.

Я уверен, что это тот же образ. Я попробовал это дважды, чтобы убедиться. Сегодня я проведу тройную проверку в офисе. Да, я делал это несколько раз. То же изображение создает разные размеры и разные символы byte[].


Хорошо, я думаю, что нашел проблему. Возможно, это была полезная информация, но я даже не думал, что это будет проблемой. Загруженный файл - это изображение, которое я изменяю. Метод изменения размера принимает byte[] (тот, который, как я думал, был некорректно закодирован), записывает его в растровое изображение. Это растровое изображение затем "перерисовывается" на новый размер с помощью PixelFormat.Format32bppRgb и InterpolationMode.HighQualityBicubic:

if (pImage.Height < maxHeight && pImage.Width < maxWidth) return pImage;  
using (pImage)  
{  
    Double xRatio = (double)pImage.Width / maxWidth;
    Double yRatio = (double)pImage.Height / maxHeight;
    Double ratio = Math.Max(xRatio, yRatio);
    int nnx = (int)Math.Floor(pImage.Width / ratio);
    int nny = (int)Math.Floor(pImage.Height / ratio);
    System.Drawing.Bitmap cpy = new System.Drawing.Bitmap(nnx, nny, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
    using (System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(cpy))
    {  
        gr.Clear(System.Drawing.Color.Transparent);

        gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

        gr.DrawImage(pImage,
            new System.Drawing.Rectangle(0, 0, nnx, nny),
            new System.Drawing.Rectangle(0, 0, pImage.Width, pImage.Height),
            System.Drawing.GraphicsUnit.Pixel);
    }
    return cpy;
}

Я изменил режим PixelFormat на "DontCare" и InterpolationMode на Default. Извините, это было бы очевидно, но я думал, что это было обработано инфраструктурой .net?

4b9b3361

Ответ 1

Windows XP и более новые os'es, такие как 7 и 8, кодируют и декодируют вещи по-разному. Что я могу предложить для вас, это кодирование вашего байтового массива на BASE64 перед передачей. Затем получите его и декодируйте обратно в массив байтов..Net имеет простые методы для кодирования и декодирования base64. Так как текст base64 равен 7 бит ascii, проблема не будет передана.