An alternative is to read the entire file in (undef $/) and then split it:

My suggestion is to put some code like this in your script:

local $/ = get_line_ending($fh);

sub get_line_ending {
	my $fh = shift;
	my $char;
	while (read $fh, $char, 1) {
		if ($char eq "\n") {
			seek $fh, 0, 0;
			return "\n";
		} elsif ($char eq "\r") {
			if (read $fh, $char, 1 and $char eq "\n") {
				seek $fh, 0, 0;
				return "\r\n";
			} else {
				seek $fh, 0, 0;
				return "\r";
			}
		}
	}
	## what, no line ending?
	## return a reasonable default
	seek $fh, 0, 0;
	return "\n";
}

This, of course assumes that you don't have some oddball case
where you have \r's in a unix file or something like that, but
if you're dealing with text files (which is the only place where
line endings should matter), that's unlikely.

Suggestions for the above code:
Move the sub into a module.
Put a byte counter in, so that you're not reading through a 5 Gig
file looking for a line ending.
I assume it's more efficient to read small chunks of bytes rather
than byte by byte.  For most text files this shouldn't matter, but
you may want to alter the reads and also the comparisons if you care.

Reply via email to