Если вопрос в этом, а других я не увидел, то ответ – нет. Потоки в std все и всегда байтовые, но вопрос в том, как интерпретировать пропускаемые через поток последовательности байт. Внутреннее и внешнее представления символов в этом потоке могут отличаться, и зачастую так и есть. Например, в файле лежит UTF8, а программа работает с std::wstring, т.е. с (не совсем так) UTF16, поэтому при вводе-выводе должно выполняться преобразование из одной формы в другую.
В файловых потоках за это отвечает фасет std::codecvt<>, который задействуется при форматном вводе/выводе. Любая локаль, даже стандартная std::locale::classic, по умолчанию содержит std::codecvt<>, который преобразует wchar_t (это если std::w(i/o)fstream) в char стандартным образом: в стандартные однобайтовые символы. Когда ты стандартную локаль заменяешь на кастомную, в std::codecvt<> всего лишь меняются правила соответствия между char и wchar_t, но преобразование в однобайтовую форму всё равно будет. Если такое поведение неприемлемо, то: либо это правило нужно изменить подменой фасета; либо – для простых операций это проще – вместо форматного ввода/вывода бинарный, он не задействует преобразование потока байтов. В первом примере у тебя использовался форматный, в следующем бинарный. Потому и разница.
P.S. Это что касается потоковых классов из Стандарта языка. CFile таковым не является, это продукт сугубо MS. Всё вышесказанное к нему может не иметь никакого отношения.