Perl: Порядок модуля File::BOM и :encoding и дефект вывода

Давайте посмотрим, вы указали второй аргумент открытой функции следующим образом:

open my $fh, ">:via(File::BOM):encoding(UTF-8)", $file or die "Cannot open $file: $!";

Здесь вы указываете сначала :via(File::BOM) и :encoding(UTF-8)", Затем выходная строка будет обрезана посередине.

Следующий сценарий пытается вывести текстовый файл UTF-8 со спецификацией: Содержимое должно представлять собой объединение строк от «xxx yyyy1» до «xxx yyyy100» с увеличением конечного номера и разделением символами «/».

#!/usr/bin/perl

# bomTest.pl

use strict;
use warnings;
use File::BOM;
use feature 'say';

my $file = '/home/cf/Desktop/foo.txt';

open my $fh, ">:via(File::BOM):encoding(UTF-8)", $file or die "Cannot open $file: $!";

say $fh 'xxx yyyy1 / xxx yyyy2 / xxx yyyy3 / xxx yyyy4 / xxx yyyy5 / xxx yyyy6 / xxx yyyy7 / xxx yyyy8 / xxx yyyy9 / xxx yyyy10 / ' .
'xxx yyyy11 / xxx yyyy12 / xxx yyyy13 / xxx yyyy14 / xxx yyyy15 / xxx yyyy16 / xxx yyyy17 / xxx yyyy18 / xxx yyyy19 / xxx yyyy20 / ' .
... snip ...
'xxx yyyy71 / xxx yyyy72 / xxx yyyy73 / xxx yyyy74 / xxx yyyy75 / xxx yyyy76 / xxx yyyy77 / xxx yyyy78 / xxx yyyy79 / xxx yyyy80 / ' .
'xxx yyyy81 / xxx yyyy82 / xxx yyyy83 / xxx yyyy84 / xxx yyyy85 / xxx yyyy86 / xxx yyyy87 / xxx yyyy88 / xxx yyyy89 / xxx yyyy90 / ' .
'xxx yyyy91 / xxx yyyy92 / xxx yyyy93 / xxx yyyy94 / xxx yyyy95 / xxx yyyy96 / xxx yyyy97 / xxx yyyy98 / xxx yyyy99 / xxx yyyy100';

close $fh;

Выходной файл foo.txt будет представлять собой файл UTF-8 со спецификацией (0x EF BB BF) в верхней части файла, но строка будет завершена в середине, как показано ниже:

xxx yyyy1 / xxx yyyy2 / xxx yyyy3 / xxx yyyy4 / xxx yyyy5 / xxx yyyy6 / xxx yyyy7 / xxx yyyy8 / xxx yyyy9 / xxx yyyy10 / xxx yyyy11 / xxx yyyy12 / xxx yyyy13 / xxx гггг14 / ххх гггг15 / ххх гггг16 / ххх гггг17 / xxx yyyy18 / xxx yyyy19 / xxx yyyy20 / ...snip... xxx yyyy71 / xxx yyyy72 / xxx yyyy73 / xxx yyyy74 / xxx yyyy75 / xxx yyyy76 / xxx yyyy77 / xxx yyyy78 / xxx 79 / ххх гг

Вывод останавливается в середине «xxx yyyy80».

Теперь, если вы измените скрипт следующим образом:

open my $fh, ">:encoding(UTF-8):via(File::BOM)", $file or die "Cannot open $file: $!";

Измененная точка — это порядок уровня ввода-вывода. Вы указали :encoding(UTF-8) первым и :via(File::BOM) последним.

Затем сценарий полностью запускается до «xxx yyyy100».

Что это за явление? Это ошибка кодировки Perl? Или еще модуль File::BOM? Или это их разумная спецификация?

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

Shawn 26.05.2024 12:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ответ уже в вопросе: Вы использовали ">:via(File::BOM):encoding(UTF-8)" тогда, когда следовало использовать ">:encoding(UTF-8):via(File::BOM)".

Из документов,

Добавьте слой via(File::BOM) поверх слоя кодировки Юникода, чтобы напечатать спецификацию в начале выходного файла. Это необходимо сделать до записи каких-либо данных. Спецификация записывается как часть первой команды печати в дескрипторе, поэтому, если вы ничего не печатаете в дескрипторе, вы не получите спецификацию.

Непонятно, какой слой находится поверх другого слоя, но пример проясняет это.

# Writing little-endian UTF-16 file with BOM:
open(HANDLE, '>:encoding(UTF-16LE):via(File::BOM)', $filename)

Ошибка ваша. Это случай ГИГО.

Другие вопросы по теме