Что сработало для меня:
В активном httpd.conf найти
<IfModule mime_module>
...
</IfModule>
Отсутствует следующее
AddType application/x-httpd-php .php
AddHandler application/x-httpd-php .php
После перезапуска apache , .php правильно разбираются.
BinaryReader.ReadInt64
по своей природе немного эндианский. Из документации:
BinaryReader читает этот тип данных в little-endian формате.
На самом деле, мы можем проверить источник для BinaryReader.ReadInt64
с помощью рефлектора.
public virtual long ReadInt64() {
this.FillBuffer(8);
uint num = (uint) (((this.m_buffer[0] |
(this.m_buffer[1] << 0x08)) |
(this.m_buffer[2] << 0x10)) |
(this.m_buffer[3] << 0x18));
uint num2 = (uint) (((this.m_buffer[4] |
(this.m_buffer[5] << 0x08)) |
(this.m_buffer[6] << 0x10)) |
(this.m_buffer[7] << 0x18));
return (long) ((num2 << 0x20) | num);
}
Показывая, что BinaryReader. ReadInt64
читается как little endian независимо от базовой машинной архитектуры.
Теперь, BitConverter.ToInt64
должен уважать endianness Вашей базовой машинной архитектуры. В рефлекторе мы видим
public static unsafe long ToInt64(byte[] value, int startIndex) {
// argument checking elided
fixed (byte* numRef = &(value[startIndex])) {
if ((startIndex % 8) == 0) {
return *(((long*) numRef));
}
if (IsLittleEndian) {
int num = (numRef[0] << 0x00) |
(numRef[1] << 0x08) |
(numRef[2] << 0x10) |
(numRef[3] << 0x18);
int num2 = (numRef[4] << 0x00) |
(numRef[5] << 0x08) |
(numRef[6] << 0x10) |
(numRef[7] << 0x18);
return (((long) ((ulong) num)) | (num2 << 0x20));
}
int num3 = (numRef[0] << 0x18) |
(numRef[1] << 0x10) |
(numRef[2] << 0x08) |
(numRef[3] << 0x00);
int num4 = (numRef[4] << 0x18) |
(numRef[5] << 0x10) |
(numRef[6] << 0x08) |
(numRef[7] << 0x00);
return (((long) ((ulong) num4)) | (num3 << 0x20));
}
Так что, если startIndex
совпадает с нулевым модулем восемь, то прямое приведение выполняется из восьми байт, начиная с адреса numRef
. Этот случай обрабатывается специально из-за проблем с выравниванием. Строка кода
return *(((long *) numRef));
транслируется непосредственно в
ldloc.0 ;pushes local 0 on stack, this is numRef
conv.i ;pop top of stack, convert to native int, push onto stack
ldind.i8 ;pop address off stack, indirect load from address as long
ret ;return to caller, return value is top of stack
Так что мы видим, что в данном случае ключом является инструкция ldind.i8
. CLI агностик насчет эндианности лежащей в основе машины. Он позволяет компилятору JIT справиться с этой проблемой. На машине little-endian ldind.i8
будет загружать более высокие адреса в более значащие биты, а на машине big-endian ldind.i8
будет загружать более высокие адреса в менее значащие байты. Поэтому в данном случае эндианность обрабатывается корректно.
В другом случае можно заметить, что существует явная проверка статического свойства BitConverter.IsLittleEndian
. В случае little endian буфер интерпретируется как little endian (так что память { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
интерпретируется как длинный 0x0706050403020100
), а в случае большого эндиана буфер интерпретируется как большой эндиан (так что память { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
интерпретируется как длинный 0x0001020304050607
). Итак, для BitConverter
все сводится к эндианности машины нижнего белья. Обращаю ваше внимание, что вы находитесь на чипе Intel в Windows 7 x64. Чипы Intel немного эндианские. Обращаю внимание, что в Reflector статический конструктор для BitConverter
определен как:
static BitConverter() {
IsLittleEndian = true;
}
Это на моей машине Windows Vista x64. (Он может отличаться, скажем, на .NET CF на XBox 360.) Нет причин для того, чтобы Windows 7 x64 отличалась. Следовательно, Вы уверены, что BitConverter.IsLittleEndian
является false
? Это должно быть true
и поэтому поведение, которое Вы видите, является правильным.
Вы находитесь на little endian машине, на которой сначала хранятся наименее значимые байты целых чисел.
.BinaryReader принимает малый Эндианский порядок: http://msdn.microsoft.com/en-us/library/system.io.binaryreader.readint64.aspx
Если вас волнует эндианность ваших байтов, Джон Скит (Jon Skeet) написал класс, позволяющий выбрать эндианский порядок при преобразовании.