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