Take the 2-minute tour ×

I'm running ActivePerl 5.8.8 on WinXP. I'd like to output an XML file as UTF-8 with UNIX line endings.

I've looked at the perldoc for binmode, but am unsure of the exact syntax (if I'm not barking up the wrong tree). The following doesn't do it (forgive my Perl - it's a learning process!):

sub SaveFile
    my($FileName, $Contents) = @_;

    my $File = "SAVE";
    unless( open($File, ">:utf-8 :unix", $FileName) )
        die("Cannot open $FileName");
    print $File @$Contents;

share|improve this question
I'm curious as to why you care about line endings. XML doesn't care. Whatever you read the file back in with shouldn't care either. –  AmbroseChapel Apr 30 '10 at 14:01
What are you intending to achieve with my $File = "SAVE"; ? –  Ether Apr 30 '10 at 17:57
@AmbroseChapel: I agree, we shouldn't care but the (Library Management System - Ex Libris' Aleph) software that sucks it up is finicky. –  Umber Ferrule May 4 '10 at 10:06

2 Answers 2

up vote 3 down vote accepted

If $Contents does not already have \n characters, print will not add them for you. You must do that yourself.

There's a couple other things that might be problematic; here's how to fix them and why.

IO Layers

To enable utf8 output, you need to use :utf8, not :utf-8. In addition, you should not have spaces in your IO layers, so it should look like `">:utf8:unix".


To open a file, you can declare the 'my $fh' in line; no need to initialize it to a string to start. It's okay, this is good practice. In addition, using or is the preferred way to catch open errors.

Changed around, your code looks like this now:

sub SaveFile
    my($FileName, $Contents) = @_;

    open my $File, ">:utf8:unix", $FileName
        or die "Cannot open $FileName";
    print $File map { "$_\n" } @$Contents;


map lets you transform your input array by adding the newlines to each line before it prints them, and does it in order.

Good luck!

share|improve this answer
That works great - thanks very much for your tips too! –  Umber Ferrule May 4 '10 at 9:51

I think you need something like this.

use strict;
use warnings;

sub save_file {
    my ($file_name, $content) = @_;
    open my $fh, ">", $file_name or die $!;
    binmode $fh, ':utf8 :unix';
    print $fh @$content;
    close $fh;

# For example.
save_file('foo.txt', [ map "$_\n", qw(foo bar baz)]);

For typical use of the 3-argument form of open, you want the file handle variable to be undefined before calling open. See the docs for details.

share|improve this answer
This outputs UTF-8 but not UNIX line endings in my XP environment. –  Umber Ferrule Apr 30 '10 at 14:00
@Umber Ferrule Not sure what the problem is. It works for me on XP, including Unix newlines. Here's a dump of the file: 666f 6f0a 6261 720a 6261 7a0a. –  FMc Apr 30 '10 at 15:07

Your Answer


