line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Bio::Root::IO; |
2
|
|
|
|
|
|
|
|
3
|
276
|
|
|
276
|
|
2128
|
use strict; |
|
276
|
|
|
|
|
579
|
|
|
276
|
|
|
|
|
6579
|
|
4
|
276
|
|
|
276
|
|
1133
|
use Symbol; |
|
276
|
|
|
|
|
483
|
|
|
276
|
|
|
|
|
13466
|
|
5
|
276
|
|
|
276
|
|
1314
|
use IO::Handle; |
|
276
|
|
|
|
|
564
|
|
|
276
|
|
|
|
|
9047
|
|
6
|
276
|
|
|
276
|
|
75098
|
use File::Copy; |
|
276
|
|
|
|
|
501009
|
|
|
276
|
|
|
|
|
13275
|
|
7
|
276
|
|
|
276
|
|
1628
|
use Fcntl; |
|
276
|
|
|
|
|
444
|
|
|
276
|
|
|
|
|
51876
|
|
8
|
276
|
|
|
276
|
|
1570
|
use base qw(Bio::Root::Root); |
|
276
|
|
|
|
|
431
|
|
|
276
|
|
|
|
|
128231
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# as of 2016, worked on most systems, but will test this in a RC |
11
|
|
|
|
|
|
|
my %modes = ( 0 => 'r', 1 => 'w', 2 => 'rw' ); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Use stream I/O in your module |
16
|
|
|
|
|
|
|
$self->{'io'} = Bio::Root::IO->new(-file => "myfile"); |
17
|
|
|
|
|
|
|
$self->{'io'}->_print("some stuff"); |
18
|
|
|
|
|
|
|
my $line = $self->{'io'}->_readline(); |
19
|
|
|
|
|
|
|
$self->{'io'}->_pushback($line); |
20
|
|
|
|
|
|
|
$self->{'io'}->close(); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# obtain platform-compatible filenames |
23
|
|
|
|
|
|
|
$path = Bio::Root::IO->catfile($dir, $subdir, $filename); |
24
|
|
|
|
|
|
|
# obtain a temporary file (created in $TEMPDIR) |
25
|
|
|
|
|
|
|
($handle) = $io->tempfile(); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 DESCRIPTION |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
This module provides methods that will usually be needed for any sort |
30
|
|
|
|
|
|
|
of file- or stream-related input/output, e.g., keeping track of a file |
31
|
|
|
|
|
|
|
handle, transient printing and reading from the file handle, a close |
32
|
|
|
|
|
|
|
method, automatically closing the handle on garbage collection, etc. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
To use this for your own code you will either want to inherit from |
35
|
|
|
|
|
|
|
this module, or instantiate an object for every file or stream you are |
36
|
|
|
|
|
|
|
dealing with. In the first case this module will most likely not be |
37
|
|
|
|
|
|
|
the first class off which your class inherits; therefore you need to |
38
|
|
|
|
|
|
|
call _initialize_io() with the named parameters in order to set file |
39
|
|
|
|
|
|
|
handle, open file, etc automatically. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
Most methods start with an underscore, indicating they are private. In |
42
|
|
|
|
|
|
|
OO speak, they are not private but protected, that is, use them in |
43
|
|
|
|
|
|
|
your module code, but a client code of your module will usually not |
44
|
|
|
|
|
|
|
want to call them (except those not starting with an underscore). |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
In addition this module contains a couple of convenience methods for |
47
|
|
|
|
|
|
|
cross-platform safe tempfile creation and similar tasks. There are |
48
|
|
|
|
|
|
|
some CPAN modules related that may not be available on all |
49
|
|
|
|
|
|
|
platforms. At present, File::Spec and File::Temp are attempted. This |
50
|
|
|
|
|
|
|
module defines $PATHSEP, $TEMPDIR, and $ROOTDIR, which will always be set, |
51
|
|
|
|
|
|
|
and $OPENFLAGS, which will be set if either of File::Spec or File::Temp fails. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
The -noclose boolean (accessed via the noclose method) prevents a |
54
|
|
|
|
|
|
|
filehandle from being closed when the IO object is cleaned up. This |
55
|
|
|
|
|
|
|
is special behavior when a object like a parser might share a |
56
|
|
|
|
|
|
|
filehandle with an object like an indexer where it is not proper to |
57
|
|
|
|
|
|
|
close the filehandle as it will continue to be reused until the end of the |
58
|
|
|
|
|
|
|
stream is reached. In general you won't want to play with this flag. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 AUTHOR Hilmar Lapp |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=cut |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
our ($FILESPECLOADED, $FILETEMPLOADED, |
65
|
|
|
|
|
|
|
$FILEPATHLOADED, $TEMPDIR, |
66
|
|
|
|
|
|
|
$PATHSEP, $ROOTDIR, |
67
|
|
|
|
|
|
|
$OPENFLAGS, $VERBOSE, |
68
|
|
|
|
|
|
|
$ONMAC, $HAS_EOL, ); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
my $TEMPCOUNTER; |
71
|
|
|
|
|
|
|
my $HAS_WIN32 = 0; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
BEGIN { |
74
|
276
|
|
|
276
|
|
853
|
$TEMPCOUNTER = 0; |
75
|
276
|
|
|
|
|
410
|
$FILESPECLOADED = 0; |
76
|
276
|
|
|
|
|
388
|
$FILETEMPLOADED = 0; |
77
|
276
|
|
|
|
|
407
|
$FILEPATHLOADED = 0; |
78
|
276
|
|
|
|
|
404
|
$VERBOSE = 0; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# try to load those modules that may cause trouble on some systems |
81
|
276
|
|
|
|
|
402
|
eval { |
82
|
276
|
|
|
|
|
1300
|
require File::Path; |
83
|
276
|
|
|
|
|
478
|
$FILEPATHLOADED = 1; |
84
|
|
|
|
|
|
|
}; |
85
|
276
|
50
|
|
|
|
1013
|
if( $@ ) { |
86
|
0
|
0
|
|
|
|
0
|
print STDERR "Cannot load File::Path: $@" if( $VERBOSE > 0 ); |
87
|
|
|
|
|
|
|
# do nothing |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# If on Win32, attempt to find Win32 package |
91
|
276
|
50
|
|
|
|
1434
|
if($^O =~ /mswin/i) { |
92
|
0
|
|
|
|
|
0
|
eval { |
93
|
0
|
|
|
|
|
0
|
require Win32; |
94
|
0
|
|
|
|
|
0
|
$HAS_WIN32 = 1; |
95
|
|
|
|
|
|
|
}; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Try to provide a path separator. Why doesn't File::Spec export this, |
99
|
|
|
|
|
|
|
# or did I miss it? |
100
|
276
|
50
|
|
|
|
1257
|
if ($^O =~ /mswin/i) { |
|
|
50
|
|
|
|
|
|
101
|
0
|
|
|
|
|
0
|
$PATHSEP = "\\"; |
102
|
|
|
|
|
|
|
} elsif($^O =~ /macos/i) { |
103
|
0
|
|
|
|
|
0
|
$PATHSEP = ":"; |
104
|
|
|
|
|
|
|
} else { # unix |
105
|
276
|
|
|
|
|
518
|
$PATHSEP = "/"; |
106
|
|
|
|
|
|
|
} |
107
|
276
|
|
|
|
|
431
|
eval { |
108
|
276
|
|
|
|
|
895
|
require File::Spec; |
109
|
276
|
|
|
|
|
425
|
$FILESPECLOADED = 1; |
110
|
276
|
|
|
|
|
22481
|
$TEMPDIR = File::Spec->tmpdir(); |
111
|
276
|
|
|
|
|
2097
|
$ROOTDIR = File::Spec->rootdir(); |
112
|
276
|
|
|
|
|
1191
|
require File::Temp; # tempfile creation |
113
|
276
|
|
|
|
|
608
|
$FILETEMPLOADED = 1; |
114
|
|
|
|
|
|
|
}; |
115
|
276
|
50
|
|
|
|
867
|
if( $@ ) { |
116
|
0
|
0
|
|
|
|
0
|
if(! defined($TEMPDIR)) { # File::Spec failed |
117
|
|
|
|
|
|
|
# determine tempdir |
118
|
0
|
0
|
0
|
|
|
0
|
if (defined $ENV{'TEMPDIR'} && -d $ENV{'TEMPDIR'} ) { |
|
|
0
|
0
|
|
|
|
|
119
|
0
|
|
|
|
|
0
|
$TEMPDIR = $ENV{'TEMPDIR'}; |
120
|
|
|
|
|
|
|
} elsif( defined $ENV{'TMPDIR'} && -d $ENV{'TMPDIR'} ) { |
121
|
0
|
|
|
|
|
0
|
$TEMPDIR = $ENV{'TMPDIR'}; |
122
|
|
|
|
|
|
|
} |
123
|
0
|
0
|
|
|
|
0
|
if($^O =~ /mswin/i) { |
|
|
0
|
|
|
|
|
|
124
|
0
|
0
|
|
|
|
0
|
$TEMPDIR = 'C:\TEMP' unless $TEMPDIR; |
125
|
0
|
|
|
|
|
0
|
$ROOTDIR = 'C:'; |
126
|
|
|
|
|
|
|
} elsif($^O =~ /macos/i) { |
127
|
0
|
0
|
|
|
|
0
|
$TEMPDIR = "" unless $TEMPDIR; # what is a reasonable default on Macs? |
128
|
0
|
|
|
|
|
0
|
$ROOTDIR = ""; # what is reasonable?? |
129
|
|
|
|
|
|
|
} else { # unix |
130
|
0
|
0
|
|
|
|
0
|
$TEMPDIR = "/tmp" unless $TEMPDIR; |
131
|
0
|
|
|
|
|
0
|
$ROOTDIR = "/"; |
132
|
|
|
|
|
|
|
} |
133
|
0
|
0
|
0
|
|
|
0
|
if (!( -d $TEMPDIR && -w $TEMPDIR )) { |
134
|
0
|
|
|
|
|
0
|
$TEMPDIR = '.'; # last resort |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
# File::Temp failed (alone, or File::Spec already failed) |
138
|
|
|
|
|
|
|
# determine open flags for tempfile creation using Fcntl |
139
|
0
|
|
|
|
|
0
|
$OPENFLAGS = O_CREAT | O_EXCL | O_RDWR; |
140
|
0
|
|
|
|
|
0
|
for my $oflag (qw/FOLLOW BINARY LARGEFILE EXLOCK NOINHERIT TEMPORARY/){ |
141
|
0
|
|
|
|
|
0
|
my ($bit, $func) = (0, "Fcntl::O_" . $oflag); |
142
|
276
|
|
|
276
|
|
2184
|
no strict 'refs'; |
|
276
|
|
|
|
|
479
|
|
|
276
|
|
|
|
|
24548
|
|
143
|
0
|
0
|
|
|
|
0
|
$OPENFLAGS |= $bit if eval { $bit = &$func(); 1 }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
} |
146
|
276
|
|
|
|
|
192937
|
$ONMAC = "\015" eq "\n"; |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head2 new |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
Title : new |
153
|
|
|
|
|
|
|
Usage : my $io = Bio::Root::IO->new( -file => 'data.txt' ); |
154
|
|
|
|
|
|
|
Function: Create new class instance. It automatically calls C<_initialize_io>. |
155
|
|
|
|
|
|
|
Args : Same named parameters as C<_initialize_io>. |
156
|
|
|
|
|
|
|
Returns : A Bio::Root::IO object |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=cut |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub new { |
161
|
9117
|
|
|
9117
|
1
|
21994
|
my ($caller, @args) = @_; |
162
|
9117
|
|
|
|
|
21889
|
my $self = $caller->SUPER::new(@args); |
163
|
9117
|
|
|
|
|
22976
|
$self->_initialize_io(@args); |
164
|
9110
|
|
|
|
|
16156
|
return $self; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=head2 _initialize_io |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
Title : _initialize_io |
171
|
|
|
|
|
|
|
Usage : $io->_initialize_io(@params); |
172
|
|
|
|
|
|
|
Function: Initializes filehandle and other properties from the parameters. |
173
|
|
|
|
|
|
|
Args : The following named parameters are currently recognized: |
174
|
|
|
|
|
|
|
-file name of file to read or write to |
175
|
|
|
|
|
|
|
-fh file handle to read or write to (mutually exclusive |
176
|
|
|
|
|
|
|
with -file and -string) |
177
|
|
|
|
|
|
|
-input name of file, or filehandle (GLOB or IO::Handle object) |
178
|
|
|
|
|
|
|
to read of write to |
179
|
|
|
|
|
|
|
-string string to read from (will be converted to filehandle) |
180
|
|
|
|
|
|
|
-url name of URL to open |
181
|
|
|
|
|
|
|
-flush boolean flag to autoflush after each write |
182
|
|
|
|
|
|
|
-noclose boolean flag, when set to true will not close a |
183
|
|
|
|
|
|
|
filehandle (must explicitly call close($io->_fh) |
184
|
|
|
|
|
|
|
-retries number of times to try a web fetch before failure |
185
|
|
|
|
|
|
|
-ua_parms when using -url, hashref of key => value parameters |
186
|
|
|
|
|
|
|
to pass to LWP::UserAgent->new(). A useful value might |
187
|
|
|
|
|
|
|
be, for example, {timeout => 60 } (ua defaults to 180s) |
188
|
|
|
|
|
|
|
Returns : True |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=cut |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub _initialize_io { |
193
|
10736
|
|
|
10736
|
|
17894
|
my($self, @args) = @_; |
194
|
|
|
|
|
|
|
|
195
|
10736
|
|
|
|
|
31062
|
$self->_register_for_cleanup(\&_io_cleanup); |
196
|
|
|
|
|
|
|
|
197
|
10736
|
|
|
|
|
40614
|
my ($input, $noclose, $file, $fh, $string, |
198
|
|
|
|
|
|
|
$flush, $url, $retries, $ua_parms) = |
199
|
|
|
|
|
|
|
$self->_rearrange([qw(INPUT NOCLOSE FILE FH STRING FLUSH URL RETRIES UA_PARMS)], |
200
|
|
|
|
|
|
|
@args); |
201
|
|
|
|
|
|
|
|
202
|
10736
|
|
|
|
|
18589
|
my $mode; |
203
|
|
|
|
|
|
|
|
204
|
10736
|
50
|
|
|
|
18276
|
if ($url) { |
205
|
0
|
|
0
|
|
|
0
|
$retries ||= 5; |
206
|
|
|
|
|
|
|
|
207
|
0
|
|
|
|
|
0
|
require LWP::UserAgent; |
208
|
0
|
|
|
|
|
0
|
my $ua = LWP::UserAgent->new(%$ua_parms); |
209
|
0
|
|
|
|
|
0
|
my $http_result; |
210
|
0
|
|
|
|
|
0
|
my ($handle, $tempfile) = $self->tempfile(); |
211
|
0
|
|
|
|
|
0
|
CORE::close($handle); |
212
|
|
|
|
|
|
|
|
213
|
0
|
|
|
|
|
0
|
for (my $try = 1 ; $try <= $retries ; $try++) { |
214
|
0
|
|
|
|
|
0
|
$http_result = $ua->get($url, ':content_file' => $tempfile); |
215
|
0
|
0
|
|
|
|
0
|
$self->warn("[$try/$retries] tried to fetch $url, but server ". |
216
|
|
|
|
|
|
|
"threw ". $http_result->code . ". retrying...") |
217
|
|
|
|
|
|
|
if !$http_result->is_success; |
218
|
0
|
0
|
|
|
|
0
|
last if $http_result->is_success; |
219
|
|
|
|
|
|
|
} |
220
|
0
|
0
|
|
|
|
0
|
$self->throw("Failed to fetch $url, server threw ".$http_result->code) |
221
|
|
|
|
|
|
|
if !$http_result->is_success; |
222
|
|
|
|
|
|
|
|
223
|
0
|
|
|
|
|
0
|
$file = $tempfile; |
224
|
0
|
|
|
|
|
0
|
$mode = '>'; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
10736
|
|
|
|
|
13655
|
delete $self->{'_readbuffer'}; |
228
|
10736
|
|
|
|
|
15215
|
delete $self->{'_filehandle'}; |
229
|
10736
|
100
|
|
|
|
19336
|
$self->noclose( $noclose) if defined $noclose; |
230
|
|
|
|
|
|
|
# determine whether the input is a file(name) or a stream |
231
|
10736
|
100
|
|
|
|
18080
|
if ($input) { |
232
|
23
|
50
|
0
|
|
|
63
|
if (ref(\$input) eq 'SCALAR') { |
|
|
0
|
0
|
|
|
|
|
233
|
|
|
|
|
|
|
# we assume that a scalar is a filename |
234
|
23
|
100
|
100
|
|
|
54
|
if ($file && ($file ne $input)) { |
235
|
1
|
|
|
|
|
11
|
$self->throw("Input file given twice: '$file' and '$input' disagree"); |
236
|
|
|
|
|
|
|
} |
237
|
22
|
|
|
|
|
31
|
$file = $input; |
238
|
|
|
|
|
|
|
} elsif (ref($input) && |
239
|
|
|
|
|
|
|
((ref($input) eq 'GLOB') || $input->isa('IO::Handle'))) { |
240
|
|
|
|
|
|
|
# input is a stream |
241
|
0
|
|
|
|
|
0
|
$fh = $input; |
242
|
|
|
|
|
|
|
} else { |
243
|
|
|
|
|
|
|
# let's be strict for now |
244
|
0
|
|
|
|
|
0
|
$self->throw("Unable to determine type of input $input: ". |
245
|
|
|
|
|
|
|
"not string and not GLOB"); |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
10735
|
100
|
100
|
|
|
23457
|
if (defined($file) && defined($fh)) { |
250
|
2
|
|
|
|
|
8
|
$self->throw("Providing both a file and a filehandle for reading - ". |
251
|
|
|
|
|
|
|
"only one please!"); |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
10733
|
100
|
|
|
|
17265
|
if ($string) { |
255
|
47
|
100
|
100
|
|
|
193
|
if (defined($file) || defined($fh)) { |
256
|
3
|
|
|
|
|
14
|
$self->throw("File or filehandle provided with -string, ". |
257
|
|
|
|
|
|
|
"please unset if you are using -string as a file"); |
258
|
|
|
|
|
|
|
} |
259
|
44
|
50
|
|
4
|
|
746
|
open $fh, '<', \$string or $self->throw("Could not read string: $!"); |
|
4
|
|
|
|
|
22
|
|
|
4
|
|
|
|
|
55
|
|
|
4
|
|
|
|
|
34
|
|
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
10730
|
100
|
100
|
|
|
26823
|
if (defined($file) && ($file ne '')) { |
263
|
1143
|
|
|
|
|
4585
|
$self->file($file); |
264
|
1143
|
|
|
|
|
3508
|
($mode, $file) = $self->cleanfile; |
265
|
1143
|
|
100
|
|
|
4734
|
$mode ||= '<'; |
266
|
1143
|
100
|
|
|
|
3348
|
my $action = ($mode =~ m/>/) ? 'write' : 'read'; |
267
|
1143
|
|
|
|
|
5117
|
$fh = Symbol::gensym(); |
268
|
1143
|
100
|
|
|
|
83110
|
open $fh, $mode, $file or $self->throw("Could not $action file '$file': $!"); |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
10729
|
100
|
|
|
|
19281
|
if (defined $fh) { |
272
|
|
|
|
|
|
|
# check filehandle to ensure it's one of: |
273
|
|
|
|
|
|
|
# a GLOB reference, as in: open(my $fh, "myfile"); |
274
|
|
|
|
|
|
|
# an IO::Handle or IO::String object |
275
|
|
|
|
|
|
|
# the UNIVERSAL::can added to fix Bug2863 |
276
|
1835
|
50
|
66
|
|
|
20438
|
unless ( ( ref $fh and ( ref $fh eq 'GLOB' ) ) |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
277
|
|
|
|
|
|
|
or ( ref $fh and ( UNIVERSAL::can( $fh, 'can' ) ) |
278
|
|
|
|
|
|
|
and ( $fh->isa('IO::Handle') |
279
|
|
|
|
|
|
|
or $fh->isa('IO::String') ) ) |
280
|
|
|
|
|
|
|
) { |
281
|
0
|
|
|
|
|
0
|
$self->throw("Object $fh does not appear to be a file handle"); |
282
|
|
|
|
|
|
|
} |
283
|
1835
|
50
|
|
|
|
4776
|
if ($HAS_EOL) { |
284
|
0
|
|
|
|
|
0
|
binmode $fh, ':raw:eol(LF-Native)'; |
285
|
|
|
|
|
|
|
} |
286
|
1835
|
|
|
|
|
6842
|
$self->_fh($fh); # if $fh not provided, defaults to STDIN and STDOUT |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
10729
|
50
|
|
|
|
33782
|
$self->_flush_on_write(defined $flush ? $flush : 1); |
290
|
|
|
|
|
|
|
|
291
|
10729
|
|
|
|
|
17360
|
return 1; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=head2 _fh |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
Title : _fh |
298
|
|
|
|
|
|
|
Usage : $io->_fh($newval); |
299
|
|
|
|
|
|
|
Function: Get or set the file handle for the stream encapsulated. |
300
|
|
|
|
|
|
|
Args : Optional filehandle to use |
301
|
|
|
|
|
|
|
Returns : Filehandle for the stream |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=cut |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub _fh { |
306
|
422518
|
|
|
422518
|
|
453365
|
my ($self, $value) = @_; |
307
|
422518
|
100
|
|
|
|
532893
|
if ( defined $value) { |
308
|
1867
|
|
|
|
|
4045
|
$self->{'_filehandle'} = $value; |
309
|
|
|
|
|
|
|
} |
310
|
422518
|
|
|
|
|
712499
|
return $self->{'_filehandle'}; |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=head2 mode |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Title : mode |
317
|
|
|
|
|
|
|
Usage : $io->mode(); |
318
|
|
|
|
|
|
|
$io->mode(-force => 1); |
319
|
|
|
|
|
|
|
Function: Determine if the object was opened for reading or writing |
320
|
|
|
|
|
|
|
Args : -force: Boolean. Once mode() has been called, the mode is cached for |
321
|
|
|
|
|
|
|
further calls to mode(). Use this argument to override this |
322
|
|
|
|
|
|
|
behavior and re-check the object's mode. |
323
|
|
|
|
|
|
|
Returns : Mode of the object: |
324
|
|
|
|
|
|
|
'r' for readable |
325
|
|
|
|
|
|
|
'w' for writable |
326
|
|
|
|
|
|
|
'rw' for readable and writable |
327
|
|
|
|
|
|
|
'?' if mode could not be determined (e.g. for a -url) |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=cut |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
sub mode { |
332
|
8
|
|
|
8
|
1
|
20
|
my ($self, %arg) = @_; |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# Method 1: IO::Handle::fdopen |
335
|
|
|
|
|
|
|
# my $iotest = new IO::Handle; |
336
|
|
|
|
|
|
|
# $iotest->fdopen( dup(fileno($fh)) , 'r' ); |
337
|
|
|
|
|
|
|
# if ($iotest->error == 0) { ... } |
338
|
|
|
|
|
|
|
# It did not actually seem to work under any platform, since there would no |
339
|
|
|
|
|
|
|
# error if the filehandle had been opened writable only. It could not be |
340
|
|
|
|
|
|
|
# hacked around when dealing with unseekable (piped) filehandles. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
# Method 2: readline, a.k.a. the <> operator |
343
|
|
|
|
|
|
|
# no warnings "io"; |
344
|
|
|
|
|
|
|
# my $line = <$fh>; |
345
|
|
|
|
|
|
|
# if (defined $line) { |
346
|
|
|
|
|
|
|
# $self->{'_mode'} = 'r'; |
347
|
|
|
|
|
|
|
# ... |
348
|
|
|
|
|
|
|
# It did not work well either because <> returns undef, i.e. querying the |
349
|
|
|
|
|
|
|
# mode() after having read an entire file returned 'w'. |
350
|
|
|
|
|
|
|
|
351
|
8
|
50
|
33
|
|
|
38
|
if ( $arg{-force} || not exists $self->{'_mode'} ) { |
352
|
|
|
|
|
|
|
# Determine stream mode |
353
|
8
|
|
|
|
|
8
|
my $mode; |
354
|
8
|
|
|
|
|
14
|
my $fh = $self->_fh; |
355
|
8
|
50
|
|
|
|
17
|
if (defined $fh) { |
356
|
|
|
|
|
|
|
# use fcntl if not Windows-based |
357
|
8
|
50
|
|
|
|
23
|
if ($^O !~ /MSWin32/) { |
358
|
8
|
|
|
|
|
30
|
my $m = fcntl($fh, F_GETFL, 0); |
359
|
8
|
50
|
|
|
|
37
|
$mode = exists $modes{$m & 3} ? $modes{$m & 3} : '?'; |
360
|
|
|
|
|
|
|
} else { |
361
|
|
|
|
|
|
|
# Determine read/write status of filehandle |
362
|
276
|
|
|
276
|
|
1898
|
no warnings 'io'; |
|
276
|
|
|
|
|
477
|
|
|
276
|
|
|
|
|
695928
|
|
363
|
0
|
0
|
|
|
|
0
|
if ( defined( read $fh, my $content, 0 ) ) { |
364
|
|
|
|
|
|
|
# Successfully read 0 bytes |
365
|
0
|
|
|
|
|
0
|
$mode = 'r' |
366
|
|
|
|
|
|
|
} |
367
|
0
|
0
|
|
|
|
0
|
if ( defined( syswrite $fh, '') ) { |
368
|
|
|
|
|
|
|
# Successfully wrote 0 bytes |
369
|
0
|
|
0
|
|
|
0
|
$mode ||= ''; |
370
|
0
|
|
|
|
|
0
|
$mode .= 'w'; |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
} else { |
374
|
|
|
|
|
|
|
# Stream does not have a filehandle... cannot determine mode |
375
|
0
|
|
|
|
|
0
|
$mode = '?'; |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
# Save mode for future use |
378
|
8
|
|
|
|
|
18
|
$self->{'_mode'} = $mode; |
379
|
|
|
|
|
|
|
} |
380
|
8
|
|
|
|
|
35
|
return $self->{'_mode'}; |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=head2 file |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
Title : file |
387
|
|
|
|
|
|
|
Usage : $io->file('>'.$file); |
388
|
|
|
|
|
|
|
my $file = $io->file; |
389
|
|
|
|
|
|
|
Function: Get or set the name of the file to read or write. |
390
|
|
|
|
|
|
|
Args : Optional file name (including its mode, e.g. '<' for reading or '>' |
391
|
|
|
|
|
|
|
for writing) |
392
|
|
|
|
|
|
|
Returns : A string representing the filename and its mode. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=cut |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
sub file { |
397
|
1149
|
|
|
1149
|
1
|
2462
|
my ($self, $value) = @_; |
398
|
1149
|
100
|
|
|
|
2680
|
if ( defined $value) { |
399
|
1143
|
|
|
|
|
2324
|
$self->{'_file'} = $value; |
400
|
|
|
|
|
|
|
} |
401
|
1149
|
|
|
|
|
1735
|
return $self->{'_file'}; |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=head2 cleanfile |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
Title : cleanfile |
408
|
|
|
|
|
|
|
Usage : my ($mode, $file) = $io->cleanfile; |
409
|
|
|
|
|
|
|
Function: Get the name of the file to read or write, stripped of its mode |
410
|
|
|
|
|
|
|
('>', '<', '+>', '>>', etc). |
411
|
|
|
|
|
|
|
Args : None |
412
|
|
|
|
|
|
|
Returns : In array context, an array of the mode and the clean filename. |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=cut |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
sub cleanfile { |
417
|
1149
|
|
|
1149
|
1
|
1984
|
my ($self) = @_; |
418
|
1149
|
|
|
|
|
8217
|
return ($self->{'_file'} =~ m/^ (\+?[><]{1,2})?\s*(.*) $/x); |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=head2 format |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
Title : format |
425
|
|
|
|
|
|
|
Usage : $io->format($newval) |
426
|
|
|
|
|
|
|
Function: Get the format of a Bio::Root::IO sequence file or filehandle. Every |
427
|
|
|
|
|
|
|
object inheriting Bio::Root::IO is guaranteed to have a format. |
428
|
|
|
|
|
|
|
Args : None |
429
|
|
|
|
|
|
|
Returns : Format of the file or filehandle, e.g. fasta, fastq, genbank, embl. |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=cut |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub format { |
434
|
12
|
|
|
12
|
1
|
82
|
my ($self) = @_; |
435
|
12
|
|
|
|
|
50
|
my $format = (split '::', ref($self))[-1]; |
436
|
12
|
|
|
|
|
56
|
return $format; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=head2 variant |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
Title : format |
443
|
|
|
|
|
|
|
Usage : $io->format($newval) |
444
|
|
|
|
|
|
|
Function: Get the variant of a Bio::Root::IO sequence file or filehandle. |
445
|
|
|
|
|
|
|
The format variant depends on the specific format used. Note that |
446
|
|
|
|
|
|
|
not all formats have variants. Also, the Bio::Root::IO-implementing |
447
|
|
|
|
|
|
|
modules that require access to variants need to define a global hash |
448
|
|
|
|
|
|
|
that has the allowed variants as its keys. |
449
|
|
|
|
|
|
|
Args : None |
450
|
|
|
|
|
|
|
Returns : Variant of the file or filehandle, e.g. sanger, solexa or illumina for |
451
|
|
|
|
|
|
|
the fastq format, or undef for formats that do not have variants. |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
=cut |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
sub variant { |
456
|
70151
|
|
|
70151
|
1
|
71029
|
my ($self, $variant) = @_; |
457
|
70151
|
100
|
|
|
|
74353
|
if (defined $variant) { |
458
|
70
|
|
|
|
|
121
|
$variant = lc $variant; |
459
|
70
|
|
|
|
|
165
|
my $var_name = '%'.ref($self).'::variant'; |
460
|
70
|
|
|
|
|
3829
|
my %ok_variants = eval $var_name; # e.g. %Bio::Assembly::IO::ace::variant |
461
|
70
|
50
|
|
|
|
316
|
if (scalar keys %ok_variants == 0) { |
462
|
0
|
|
|
|
|
0
|
$self->throw("Could not validate variant because global variant ". |
463
|
|
|
|
|
|
|
"$var_name was not set or was empty\n"); |
464
|
|
|
|
|
|
|
} |
465
|
70
|
50
|
|
|
|
168
|
if (not exists $ok_variants{$variant}) { |
466
|
0
|
|
|
|
|
0
|
$self->throw("$variant is not a valid variant of the " . |
467
|
|
|
|
|
|
|
$self->format . ' format'); |
468
|
|
|
|
|
|
|
} |
469
|
70
|
|
|
|
|
246
|
$self->{variant} = $variant; |
470
|
|
|
|
|
|
|
} |
471
|
70151
|
|
|
|
|
135085
|
return $self->{variant}; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
=head2 _print |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
Title : _print |
478
|
|
|
|
|
|
|
Usage : $io->_print(@lines) |
479
|
|
|
|
|
|
|
Function: Print lines of text to the IO stream object. |
480
|
|
|
|
|
|
|
Args : List of strings to print |
481
|
|
|
|
|
|
|
Returns : True on success, undef on failure |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=cut |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
sub _print { |
486
|
27585
|
|
|
27585
|
|
26275
|
my $self = shift; |
487
|
27585
|
|
50
|
|
|
31262
|
my $fh = $self->_fh() || \*STDOUT; |
488
|
27585
|
|
|
|
|
53028
|
my $ret = print $fh @_; |
489
|
27585
|
|
|
|
|
58645
|
return $ret; |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=head2 _insert |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
Title : _insert |
496
|
|
|
|
|
|
|
Usage : $io->_insert($string,1) |
497
|
|
|
|
|
|
|
Function: Insert some text in a file at the given line number (1-based). |
498
|
|
|
|
|
|
|
Args : * string to write in file |
499
|
|
|
|
|
|
|
* line number to insert the string at |
500
|
|
|
|
|
|
|
Returns : True |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=cut |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
sub _insert { |
505
|
2
|
|
|
2
|
|
7
|
my ($self, $string, $line_num) = @_; |
506
|
|
|
|
|
|
|
# Line number check |
507
|
2
|
50
|
|
|
|
10
|
if ($line_num < 1) { |
508
|
0
|
|
|
|
|
0
|
$self->throw("Could not insert text at line $line_num: the minimum ". |
509
|
|
|
|
|
|
|
"line number possible is 1."); |
510
|
|
|
|
|
|
|
} |
511
|
|
|
|
|
|
|
# File check |
512
|
2
|
|
|
|
|
8
|
my ($mode, $file) = $self->cleanfile; |
513
|
2
|
50
|
|
|
|
8
|
if (not defined $file) { |
514
|
0
|
|
|
|
|
0
|
$self->throw('Could not insert a line: IO object was initialized with '. |
515
|
|
|
|
|
|
|
'something else than a file.'); |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
# Everything that needs to be written is written before we read it |
518
|
2
|
|
|
|
|
10
|
$self->flush; |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
# Edit the file line by line (no slurping) |
521
|
2
|
|
|
|
|
5
|
$self->close; |
522
|
2
|
|
|
|
|
4
|
my $temp_file; |
523
|
2
|
|
|
|
|
4
|
my $number = 0; |
524
|
2
|
|
|
|
|
84
|
while (-e "$file.$number.temp") { |
525
|
0
|
|
|
|
|
0
|
$number++; |
526
|
|
|
|
|
|
|
} |
527
|
2
|
|
|
|
|
7
|
$temp_file = "$file.$number.temp"; |
528
|
2
|
|
|
|
|
10
|
copy($file, $temp_file); |
529
|
2
|
50
|
|
|
|
445
|
open my $fh1, '<', $temp_file or $self->throw("Could not read temporary file '$temp_file': $!"); |
530
|
2
|
50
|
|
|
|
781
|
open my $fh2, '>', $file or $self->throw("Could not write file '$file': $!"); |
531
|
2
|
|
|
|
|
30
|
while (my $line = <$fh1>) { |
532
|
2
|
100
|
|
|
|
10
|
if ($. == $line_num) { # right line for new data |
533
|
1
|
|
|
|
|
7
|
print $fh2 $string . $line; |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
else { |
536
|
1
|
|
|
|
|
7
|
print $fh2 $line; |
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
} |
539
|
2
|
|
|
|
|
10
|
CORE::close $fh1; |
540
|
2
|
|
|
|
|
45
|
CORE::close $fh2; |
541
|
2
|
50
|
|
|
|
74
|
unlink $temp_file or $self->throw("Could not delete temporary file '$temp_file': $!"); |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
# Line number check (again) |
544
|
2
|
50
|
33
|
|
|
17
|
if ( $. > 0 && $line_num > $. ) { |
545
|
0
|
|
|
|
|
0
|
$self->throw("Could not insert text at line $line_num: there are only ". |
546
|
|
|
|
|
|
|
"$. lines in file '$file'"); |
547
|
|
|
|
|
|
|
} |
548
|
|
|
|
|
|
|
# Re-open the file in append mode to be ready to add text at the end of it |
549
|
|
|
|
|
|
|
# when the next _print() statement comes |
550
|
2
|
50
|
|
|
|
51
|
open my $new_fh, '>>', $file or $self->throw("Could not append to file '$file': $!"); |
551
|
2
|
|
|
|
|
10
|
$self->_fh($new_fh); |
552
|
|
|
|
|
|
|
# If file is empty and we're inserting at line 1, simply append text to file |
553
|
2
|
100
|
66
|
|
|
16
|
if ( $. == 0 && $line_num == 1 ) { |
554
|
1
|
|
|
|
|
6
|
$self->_print($string); |
555
|
|
|
|
|
|
|
} |
556
|
2
|
|
|
|
|
18
|
return 1; |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
=head2 _readline |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
Title : _readline |
563
|
|
|
|
|
|
|
Usage : local $Bio::Root::IO::HAS_EOL = 1; |
564
|
|
|
|
|
|
|
my $io = Bio::Root::IO->new(-file => 'data.txt'); |
565
|
|
|
|
|
|
|
my $line = $io->_readline(); |
566
|
|
|
|
|
|
|
$io->close; |
567
|
|
|
|
|
|
|
Function: Read a line of input and normalize all end of line characters. |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
End of line characters are typically "\n" on Linux platforms, "\r\n" |
570
|
|
|
|
|
|
|
on Windows and "\r" on older Mac OS. By default, the _readline() |
571
|
|
|
|
|
|
|
method uses the value of $/, Perl's input record separator, to |
572
|
|
|
|
|
|
|
detect the end of each line. This means that you will not get the |
573
|
|
|
|
|
|
|
expected lines if your input has Mac-formatted end of line characters. |
574
|
|
|
|
|
|
|
Also, note that the current implementation does not handle pushed |
575
|
|
|
|
|
|
|
back input correctly unless the pushed back input ends with the |
576
|
|
|
|
|
|
|
value of $/. For each line parsed, its line ending, e.g. "\r\n" is |
577
|
|
|
|
|
|
|
converted to "\n", unless you provide the -raw argument. |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
Altogether it is easier to let the PerlIO::eol module automatically |
580
|
|
|
|
|
|
|
detect the proper end of line character and normalize it to "\n". Do |
581
|
|
|
|
|
|
|
so by setting $Bio::Root::IO::HAS_EOL to 1. |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
Args : -raw : Avoid converting end of line characters to "\n" This option |
584
|
|
|
|
|
|
|
has no effect when using $Bio::Root::IO::HAS_EOL = 1. |
585
|
|
|
|
|
|
|
Returns : Line of input, or undef when there is nothing to read anymore |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=cut |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
sub _readline { |
590
|
379112
|
|
|
379112
|
|
467924
|
my ($self, %param) = @_; |
591
|
379112
|
100
|
|
|
|
450794
|
my $fh = $self->_fh or return; |
592
|
379100
|
|
|
|
|
356386
|
my $line; |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
# if the buffer been filled by _pushback then return the buffer |
595
|
|
|
|
|
|
|
# contents, rather than read from the filehandle |
596
|
379100
|
100
|
|
|
|
324471
|
if( @{$self->{'_readbuffer'} || [] } ) { |
|
379100
|
100
|
|
|
|
808859
|
|
597
|
1483
|
|
|
|
|
1637
|
$line = shift @{$self->{'_readbuffer'}}; |
|
1483
|
|
|
|
|
3041
|
|
598
|
|
|
|
|
|
|
} else { |
599
|
377617
|
|
|
|
|
644650
|
$line = <$fh>; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
# Note: In Windows the "-raw" parameter has no effect, because Perl already discards |
603
|
|
|
|
|
|
|
# the '\r' from the line when reading in text mode from the filehandle |
604
|
|
|
|
|
|
|
# ($line = <$fh>), and put it back automatically when printing |
605
|
379100
|
100
|
66
|
|
|
1194565
|
if( !$HAS_EOL && !$param{-raw} && (defined $line) ) { |
|
|
|
100
|
|
|
|
|
606
|
|
|
|
|
|
|
# don't strip line endings if -raw or $HAS_EOL is specified |
607
|
378525
|
|
|
|
|
494364
|
$line =~ s/\015\012/\012/g; # Change all CR/LF pairs to LF |
608
|
378525
|
50
|
|
|
|
573891
|
$line =~ tr/\015/\n/ unless $ONMAC; # Change all single CRs to NEWLINE |
609
|
|
|
|
|
|
|
} |
610
|
379100
|
|
|
|
|
944091
|
return $line; |
611
|
|
|
|
|
|
|
} |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=head2 _pushback |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
Title : _pushback |
617
|
|
|
|
|
|
|
Usage : $io->_pushback($newvalue) |
618
|
|
|
|
|
|
|
Function: Puts a line previously read with _readline back into a buffer. |
619
|
|
|
|
|
|
|
buffer can hold as many lines as system memory permits. |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
Note that this is only supported for pushing back data ending with |
622
|
|
|
|
|
|
|
the current, localized value of $/. Using this method to push |
623
|
|
|
|
|
|
|
modified data back onto the buffer stack is not supported; see bug |
624
|
|
|
|
|
|
|
843. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
Args : newvalue |
627
|
|
|
|
|
|
|
Returns : True |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=cut |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
# fix for bug 843, this reveals some unsupported behavior |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
#sub _pushback { |
634
|
|
|
|
|
|
|
# my ($self, $value) = @_; |
635
|
|
|
|
|
|
|
# if (index($value, $/) >= 0) { |
636
|
|
|
|
|
|
|
# push @{$self->{'_readbuffer'}}, $value; |
637
|
|
|
|
|
|
|
# } else { |
638
|
|
|
|
|
|
|
# $self->throw("Pushing modifed data back not supported: $value"); |
639
|
|
|
|
|
|
|
# } |
640
|
|
|
|
|
|
|
#} |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
sub _pushback { |
643
|
1504
|
|
|
1504
|
|
2757
|
my ($self, $value) = @_; |
644
|
1504
|
100
|
|
|
|
2846
|
return unless $value; |
645
|
1502
|
|
|
|
|
1881
|
unshift @{$self->{'_readbuffer'}}, $value; |
|
1502
|
|
|
|
|
3779
|
|
646
|
1502
|
|
|
|
|
2711
|
return 1; |
647
|
|
|
|
|
|
|
} |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
=head2 close |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
Title : close |
653
|
|
|
|
|
|
|
Usage : $io->close() |
654
|
|
|
|
|
|
|
Function: Closes the file handle associated with this IO instance, |
655
|
|
|
|
|
|
|
excepted if -noclose was specified. |
656
|
|
|
|
|
|
|
Args : None |
657
|
|
|
|
|
|
|
Returns : True |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
=cut |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
sub close { |
662
|
11077
|
|
|
11077
|
1
|
16324
|
my ($self) = @_; |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
# do not close if we explicitly asked not to |
665
|
11077
|
100
|
|
|
|
21553
|
return if $self->noclose; |
666
|
|
|
|
|
|
|
|
667
|
11028
|
100
|
|
|
|
24249
|
if( defined( my $fh = $self->{'_filehandle'} )) { |
668
|
1617
|
|
|
|
|
5591
|
$self->flush; |
669
|
1617
|
50
|
66
|
|
|
11664
|
return if ref $fh eq 'GLOB' && ( |
|
|
|
66
|
|
|
|
|
670
|
|
|
|
|
|
|
\*STDOUT == $fh || \*STDERR == $fh || \*STDIN == $fh |
671
|
|
|
|
|
|
|
); |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# don't close IO::Strings |
674
|
1616
|
100
|
66
|
|
|
29180
|
CORE::close $fh unless ref $fh && $fh->isa('IO::String'); |
675
|
|
|
|
|
|
|
} |
676
|
11027
|
|
|
|
|
17582
|
$self->{'_filehandle'} = undef; |
677
|
11027
|
|
|
|
|
13687
|
delete $self->{'_readbuffer'}; |
678
|
11027
|
|
|
|
|
23422
|
return 1; |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=head2 flush |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
Title : flush |
685
|
|
|
|
|
|
|
Usage : $io->flush() |
686
|
|
|
|
|
|
|
Function: Flushes the filehandle |
687
|
|
|
|
|
|
|
Args : None |
688
|
|
|
|
|
|
|
Returns : True |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
=cut |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
sub flush { |
693
|
2278
|
|
|
2278
|
1
|
4125
|
my ($self) = shift; |
694
|
|
|
|
|
|
|
|
695
|
2278
|
50
|
|
|
|
6185
|
if( !defined $self->{'_filehandle'} ) { |
696
|
0
|
|
|
|
|
0
|
$self->throw("Flush failed: no filehandle was active"); |
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
|
699
|
2278
|
100
|
|
|
|
11485
|
if( ref($self->{'_filehandle'}) =~ /GLOB/ ) { |
700
|
1225
|
|
|
|
|
5060
|
my $oldh = select($self->{'_filehandle'}); |
701
|
1225
|
|
|
|
|
8149
|
$| = 1; |
702
|
1225
|
|
|
|
|
4012
|
select($oldh); |
703
|
|
|
|
|
|
|
} else { |
704
|
1053
|
|
|
|
|
5570
|
$self->{'_filehandle'}->flush(); |
705
|
|
|
|
|
|
|
} |
706
|
2278
|
|
|
|
|
5443
|
return 1; |
707
|
|
|
|
|
|
|
} |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
=head2 noclose |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
Title : noclose |
713
|
|
|
|
|
|
|
Usage : $io->noclose($newval) |
714
|
|
|
|
|
|
|
Function: Get or set the NOCLOSE flag - setting this to true will prevent a |
715
|
|
|
|
|
|
|
filehandle from being closed when an object is cleaned up or |
716
|
|
|
|
|
|
|
explicitly closed. |
717
|
|
|
|
|
|
|
Args : Optional new value (a scalar or undef) |
718
|
|
|
|
|
|
|
Returns : Value of noclose (a scalar) |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
=cut |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
sub noclose { |
723
|
11110
|
|
|
11110
|
1
|
13909
|
my $self = shift; |
724
|
11110
|
100
|
|
|
|
20830
|
return $self->{'_noclose'} = shift if @_; |
725
|
11077
|
|
|
|
|
22981
|
return $self->{'_noclose'}; |
726
|
|
|
|
|
|
|
} |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
=head2 _io_cleanup |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
=cut |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
sub _io_cleanup { |
734
|
9404
|
|
|
9404
|
|
14372
|
my ($self) = @_; |
735
|
9404
|
|
|
|
|
22467
|
$self->close(); |
736
|
9404
|
|
|
|
|
19262
|
my $v = $self->verbose; |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# we are planning to cleanup temp files no matter what |
739
|
9404
|
50
|
66
|
|
|
22294
|
if ( exists($self->{'_rootio_tempfiles'}) |
|
|
|
66
|
|
|
|
|
740
|
|
|
|
|
|
|
and ref($self->{'_rootio_tempfiles'}) =~ /array/i |
741
|
|
|
|
|
|
|
and not $self->save_tempfiles |
742
|
|
|
|
|
|
|
) { |
743
|
34
|
50
|
|
|
|
59
|
if( $v > 0 ) { |
744
|
|
|
|
|
|
|
warn( "going to remove files ", |
745
|
0
|
|
|
|
|
0
|
join(",", @{$self->{'_rootio_tempfiles'}}), |
|
0
|
|
|
|
|
0
|
|
746
|
|
|
|
|
|
|
"\n"); |
747
|
|
|
|
|
|
|
} |
748
|
34
|
|
|
|
|
37
|
unlink (@{$self->{'_rootio_tempfiles'}} ); |
|
34
|
|
|
|
|
557
|
|
749
|
|
|
|
|
|
|
} |
750
|
|
|
|
|
|
|
# cleanup if we are not using File::Temp |
751
|
9404
|
0
|
33
|
|
|
48981
|
if ( $self->{'_cleanuptempdir'} |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
752
|
|
|
|
|
|
|
and exists($self->{'_rootio_tempdirs'}) |
753
|
|
|
|
|
|
|
and ref($self->{'_rootio_tempdirs'}) =~ /array/i |
754
|
|
|
|
|
|
|
and not $self->save_tempfiles |
755
|
|
|
|
|
|
|
) { |
756
|
0
|
0
|
|
|
|
0
|
if( $v > 0 ) { |
757
|
|
|
|
|
|
|
warn( "going to remove dirs ", |
758
|
0
|
|
|
|
|
0
|
join(",", @{$self->{'_rootio_tempdirs'}}), |
|
0
|
|
|
|
|
0
|
|
759
|
|
|
|
|
|
|
"\n"); |
760
|
|
|
|
|
|
|
} |
761
|
0
|
|
|
|
|
0
|
$self->rmtree( $self->{'_rootio_tempdirs'}); |
762
|
|
|
|
|
|
|
} |
763
|
|
|
|
|
|
|
} |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
=head2 exists_exe |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
Title : exists_exe |
769
|
|
|
|
|
|
|
Usage : $exists = $io->exists_exe('clustalw'); |
770
|
|
|
|
|
|
|
$exists = Bio::Root::IO->exists_exe('clustalw') |
771
|
|
|
|
|
|
|
$exists = Bio::Root::IO::exists_exe('clustalw') |
772
|
|
|
|
|
|
|
Function: Determines whether the given executable exists either as file |
773
|
|
|
|
|
|
|
or within the path environment. The latter requires File::Spec |
774
|
|
|
|
|
|
|
to be installed. |
775
|
|
|
|
|
|
|
On Win32-based system, .exe is automatically appended to the program |
776
|
|
|
|
|
|
|
name unless the program name already ends in .exe. |
777
|
|
|
|
|
|
|
Args : Name of the executable |
778
|
|
|
|
|
|
|
Returns : 1 if the given program is callable as an executable, and 0 otherwise |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
=cut |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
sub exists_exe { |
783
|
3
|
|
|
3
|
1
|
8
|
my ($self, $exe) = @_; |
784
|
3
|
50
|
|
|
|
7
|
$self->throw("Must pass a defined value to exists_exe") unless defined $exe; |
785
|
3
|
50
|
33
|
|
|
9
|
$exe = $self if (!(ref($self) || $exe)); |
786
|
3
|
50
|
33
|
|
|
14
|
$exe .= '.exe' if(($^O =~ /mswin/i) && ($exe !~ /\.(exe|com|bat|cmd)$/i)); |
787
|
3
|
100
|
100
|
|
|
36
|
return $exe if ( -f $exe && -x $exe ); # full path and exists |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
# Ewan's comment. I don't think we need this. People should not be |
790
|
|
|
|
|
|
|
# asking for a program with a pathseparator starting it |
791
|
|
|
|
|
|
|
# $exe =~ s/^$PATHSEP//; |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
# Not a full path, or does not exist. Let's see whether it's in the path. |
794
|
2
|
50
|
|
|
|
6
|
if($FILESPECLOADED) { |
795
|
2
|
|
|
|
|
49
|
for my $dir (File::Spec->path()) { |
796
|
18
|
|
|
|
|
49
|
my $f = Bio::Root::IO->catfile($dir, $exe); |
797
|
18
|
50
|
33
|
|
|
348
|
return $f if( -f $f && -x $f ); |
798
|
|
|
|
|
|
|
} |
799
|
|
|
|
|
|
|
} |
800
|
2
|
|
|
|
|
12
|
return 0; |
801
|
|
|
|
|
|
|
} |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
=head2 tempfile |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
Title : tempfile |
807
|
|
|
|
|
|
|
Usage : my ($handle,$tempfile) = $io->tempfile(); |
808
|
|
|
|
|
|
|
Function: Create a temporary filename and a handle opened for reading and |
809
|
|
|
|
|
|
|
writing. |
810
|
|
|
|
|
|
|
Caveats: If you do not have File::Temp on your system you should |
811
|
|
|
|
|
|
|
avoid specifying TEMPLATE and SUFFIX. |
812
|
|
|
|
|
|
|
Args : Named parameters compatible with File::Temp: DIR (defaults to |
813
|
|
|
|
|
|
|
$Bio::Root::IO::TEMPDIR), TEMPLATE, SUFFIX. |
814
|
|
|
|
|
|
|
Returns : A 2-element array, consisting of temporary handle and temporary |
815
|
|
|
|
|
|
|
file name. |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
=cut |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
sub tempfile { |
820
|
40
|
|
|
40
|
1
|
1931
|
my ($self, @args) = @_; |
821
|
40
|
|
|
|
|
54
|
my ($tfh, $file); |
822
|
40
|
|
|
|
|
130
|
my %params = @args; |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
# map between naming with and without dash |
825
|
40
|
|
|
|
|
98
|
for my $key (keys(%params)) { |
826
|
51
|
50
|
|
|
|
110
|
if( $key =~ /^-/ ) { |
827
|
0
|
|
|
|
|
0
|
my $v = $params{$key}; |
828
|
0
|
|
|
|
|
0
|
delete $params{$key}; |
829
|
0
|
|
|
|
|
0
|
$params{uc(substr($key,1))} = $v; |
830
|
|
|
|
|
|
|
} else { |
831
|
|
|
|
|
|
|
# this is to upper case |
832
|
51
|
|
|
|
|
71
|
my $v = $params{$key}; |
833
|
51
|
|
|
|
|
62
|
delete $params{$key}; |
834
|
51
|
|
|
|
|
116
|
$params{uc($key)} = $v; |
835
|
|
|
|
|
|
|
} |
836
|
|
|
|
|
|
|
} |
837
|
40
|
100
|
|
|
|
130
|
$params{'DIR'} = $TEMPDIR if(! exists($params{'DIR'})); |
838
|
40
|
100
|
66
|
|
|
140
|
unless (exists $params{'UNLINK'} && |
|
|
|
66
|
|
|
|
|
839
|
|
|
|
|
|
|
defined $params{'UNLINK'} && |
840
|
|
|
|
|
|
|
! $params{'UNLINK'} ) { |
841
|
35
|
|
|
|
|
78
|
$params{'UNLINK'} = 1; |
842
|
|
|
|
|
|
|
} else { |
843
|
5
|
|
|
|
|
8
|
$params{'UNLINK'} = 0; |
844
|
|
|
|
|
|
|
} |
845
|
|
|
|
|
|
|
|
846
|
40
|
50
|
|
|
|
64
|
if($FILETEMPLOADED) { |
847
|
40
|
100
|
|
|
|
73
|
if(exists($params{'TEMPLATE'})) { |
848
|
4
|
|
|
|
|
6
|
my $template = $params{'TEMPLATE'}; |
849
|
4
|
|
|
|
|
4
|
delete $params{'TEMPLATE'}; |
850
|
4
|
|
|
|
|
14
|
($tfh, $file) = File::Temp::tempfile($template, %params); |
851
|
|
|
|
|
|
|
} else { |
852
|
36
|
|
|
|
|
122
|
($tfh, $file) = File::Temp::tempfile(%params); |
853
|
|
|
|
|
|
|
} |
854
|
|
|
|
|
|
|
} else { |
855
|
0
|
|
|
|
|
0
|
my $dir = $params{'DIR'}; |
856
|
|
|
|
|
|
|
$file = $self->catfile( |
857
|
|
|
|
|
|
|
$dir, |
858
|
|
|
|
|
|
|
(exists($params{'TEMPLATE'}) ? |
859
|
|
|
|
|
|
|
$params{'TEMPLATE'} : |
860
|
0
|
0
|
0
|
|
|
0
|
sprintf( "%s.%s.%s", $ENV{USER} || 'unknown', $$, $TEMPCOUNTER++)) |
861
|
|
|
|
|
|
|
); |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
# sneakiness for getting around long filenames on Win32? |
864
|
0
|
0
|
|
|
|
0
|
if( $HAS_WIN32 ) { |
865
|
0
|
|
|
|
|
0
|
$file = Win32::GetShortPathName($file); |
866
|
|
|
|
|
|
|
} |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
# Try to make sure this will be marked close-on-exec |
869
|
|
|
|
|
|
|
# XXX: Win32 doesn't respect this, nor the proper fcntl, |
870
|
|
|
|
|
|
|
# but may have O_NOINHERIT. This may or may not be in Fcntl. |
871
|
0
|
|
|
|
|
0
|
local $^F = 2; |
872
|
|
|
|
|
|
|
# Store callers umask |
873
|
0
|
|
|
|
|
0
|
my $umask = umask(); |
874
|
|
|
|
|
|
|
# Set a known umaskr |
875
|
0
|
|
|
|
|
0
|
umask(066); |
876
|
|
|
|
|
|
|
# Attempt to open the file |
877
|
0
|
0
|
|
|
|
0
|
if ( sysopen($tfh, $file, $OPENFLAGS, 0600) ) { |
878
|
|
|
|
|
|
|
# Reset umask |
879
|
0
|
|
|
|
|
0
|
umask($umask); |
880
|
|
|
|
|
|
|
} else { |
881
|
0
|
|
|
|
|
0
|
$self->throw("Could not write temporary file '$file': $!"); |
882
|
|
|
|
|
|
|
} |
883
|
|
|
|
|
|
|
} |
884
|
|
|
|
|
|
|
|
885
|
40
|
100
|
|
|
|
10986
|
if( $params{'UNLINK'} ) { |
886
|
35
|
|
|
|
|
46
|
push @{$self->{'_rootio_tempfiles'}}, $file; |
|
35
|
|
|
|
|
89
|
|
887
|
|
|
|
|
|
|
} |
888
|
|
|
|
|
|
|
|
889
|
40
|
100
|
|
|
|
178
|
return wantarray ? ($tfh,$file) : $tfh; |
890
|
|
|
|
|
|
|
} |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
=head2 tempdir |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
Title : tempdir |
896
|
|
|
|
|
|
|
Usage : my ($tempdir) = $io->tempdir(CLEANUP=>1); |
897
|
|
|
|
|
|
|
Function: Creates and returns the name of a new temporary directory. |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
Note that you should not use this function for obtaining "the" |
900
|
|
|
|
|
|
|
temp directory. Use $Bio::Root::IO::TEMPDIR for that. Calling this |
901
|
|
|
|
|
|
|
method will in fact create a new directory. |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
Args : args - ( key CLEANUP ) indicates whether or not to cleanup |
904
|
|
|
|
|
|
|
dir on object destruction, other keys as specified by File::Temp |
905
|
|
|
|
|
|
|
Returns : The name of a new temporary directory. |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
=cut |
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
sub tempdir { |
910
|
31
|
|
|
31
|
1
|
62
|
my ($self, @args) = @_; |
911
|
31
|
50
|
33
|
|
|
275
|
if ($FILETEMPLOADED && File::Temp->can('tempdir')) { |
912
|
31
|
|
|
|
|
94
|
return File::Temp::tempdir(@args); |
913
|
|
|
|
|
|
|
} |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
# we have to do this ourselves, not good |
916
|
|
|
|
|
|
|
# we are planning to cleanup temp files no matter what |
917
|
0
|
|
|
|
|
0
|
my %params = @args; |
918
|
0
|
|
|
|
|
0
|
print "cleanup is " . $params{CLEANUP} . "\n"; |
919
|
|
|
|
|
|
|
$self->{'_cleanuptempdir'} = ( defined $params{CLEANUP} && |
920
|
0
|
|
0
|
|
|
0
|
$params{CLEANUP} == 1); |
921
|
|
|
|
|
|
|
my $tdir = $self->catfile( $TEMPDIR, |
922
|
|
|
|
|
|
|
sprintf("dir_%s-%s-%s", |
923
|
0
|
|
0
|
|
|
0
|
$ENV{USER} || 'unknown', |
924
|
|
|
|
|
|
|
$$, |
925
|
|
|
|
|
|
|
$TEMPCOUNTER++)); |
926
|
0
|
|
|
|
|
0
|
mkdir($tdir, 0755); |
927
|
0
|
|
|
|
|
0
|
push @{$self->{'_rootio_tempdirs'}}, $tdir; |
|
0
|
|
|
|
|
0
|
|
928
|
0
|
|
|
|
|
0
|
return $tdir; |
929
|
|
|
|
|
|
|
} |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
=head2 catfile |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
Title : catfile |
935
|
|
|
|
|
|
|
Usage : $path = Bio::Root::IO->catfile(@dirs, $filename); |
936
|
|
|
|
|
|
|
Function: Constructs a full pathname in a cross-platform safe way. |
937
|
|
|
|
|
|
|
|
938
|
|
|
|
|
|
|
If File::Spec exists on your system, this routine will merely |
939
|
|
|
|
|
|
|
delegate to it. Otherwise it tries to make a good guess. |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
You should use this method whenever you construct a path name |
942
|
|
|
|
|
|
|
from directory and filename. Otherwise you risk cross-platform |
943
|
|
|
|
|
|
|
compatibility of your code. |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
You can call this method both as a class and an instance method. |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
Args : components of the pathname (directories and filename, NOT an |
948
|
|
|
|
|
|
|
extension) |
949
|
|
|
|
|
|
|
Returns : a string |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
=cut |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
sub catfile { |
954
|
8868
|
|
|
8868
|
1
|
22699
|
my ($self, @args) = @_; |
955
|
|
|
|
|
|
|
|
956
|
8868
|
50
|
|
|
|
107309
|
return File::Spec->catfile(@args) if $FILESPECLOADED; |
957
|
|
|
|
|
|
|
# this is clumsy and not very appealing, but how do we specify the |
958
|
|
|
|
|
|
|
# root directory? |
959
|
0
|
0
|
|
|
|
0
|
if($args[0] eq '/') { |
960
|
0
|
|
|
|
|
0
|
$args[0] = $ROOTDIR; |
961
|
|
|
|
|
|
|
} |
962
|
0
|
|
|
|
|
0
|
return join($PATHSEP, @args); |
963
|
|
|
|
|
|
|
} |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
=head2 rmtree |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
Title : rmtree |
969
|
|
|
|
|
|
|
Usage : Bio::Root::IO->rmtree($dirname ); |
970
|
|
|
|
|
|
|
Function: Remove a full directory tree |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
If File::Path exists on your system, this routine will merely |
973
|
|
|
|
|
|
|
delegate to it. Otherwise it runs a local version of that code. |
974
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
You should use this method to remove directories which contain |
976
|
|
|
|
|
|
|
files. |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
You can call this method both as a class and an instance method. |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
Args : roots - rootdir to delete or reference to list of dirs |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
verbose - a boolean value, which if TRUE will cause |
983
|
|
|
|
|
|
|
C to print a message each time it |
984
|
|
|
|
|
|
|
examines a file, giving the name of the file, and |
985
|
|
|
|
|
|
|
indicating whether it's using C or |
986
|
|
|
|
|
|
|
C to remove it, or that it's skipping it. |
987
|
|
|
|
|
|
|
(defaults to FALSE) |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
safe - a boolean value, which if TRUE will cause C |
990
|
|
|
|
|
|
|
to skip any files to which you do not have delete |
991
|
|
|
|
|
|
|
access (if running under VMS) or write access (if |
992
|
|
|
|
|
|
|
running under another OS). This will change in the |
993
|
|
|
|
|
|
|
future when a criterion for 'delete permission' |
994
|
|
|
|
|
|
|
under OSs other than VMS is settled. (defaults to |
995
|
|
|
|
|
|
|
FALSE) |
996
|
|
|
|
|
|
|
Returns : number of files successfully deleted |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
=cut |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
# taken straight from File::Path VERSION = "1.0403" |
1001
|
|
|
|
|
|
|
sub rmtree { |
1002
|
0
|
|
|
0
|
1
|
0
|
my ($self, $roots, $verbose, $safe) = @_; |
1003
|
0
|
0
|
|
|
|
0
|
if ( $FILEPATHLOADED ) { |
1004
|
0
|
|
|
|
|
0
|
return File::Path::rmtree ($roots, $verbose, $safe); |
1005
|
|
|
|
|
|
|
} |
1006
|
|
|
|
|
|
|
|
1007
|
0
|
|
0
|
|
|
0
|
my $force_writable = ($^O eq 'os2' || $^O eq 'dos' || $^O eq 'MSWin32' || |
1008
|
|
|
|
|
|
|
$^O eq 'amigaos' || $^O eq 'cygwin'); |
1009
|
0
|
|
|
|
|
0
|
my $Is_VMS = $^O eq 'VMS'; |
1010
|
|
|
|
|
|
|
|
1011
|
0
|
|
|
|
|
0
|
my @files; |
1012
|
0
|
|
|
|
|
0
|
my $count = 0; |
1013
|
0
|
|
0
|
|
|
0
|
$verbose ||= 0; |
1014
|
0
|
|
0
|
|
|
0
|
$safe ||= 0; |
1015
|
0
|
0
|
0
|
|
|
0
|
if ( defined($roots) && length($roots) ) { |
1016
|
0
|
0
|
|
|
|
0
|
$roots = [$roots] unless ref $roots; |
1017
|
|
|
|
|
|
|
} else { |
1018
|
0
|
|
|
|
|
0
|
$self->warn("No root path(s) specified\n"); |
1019
|
0
|
|
|
|
|
0
|
return 0; |
1020
|
|
|
|
|
|
|
} |
1021
|
|
|
|
|
|
|
|
1022
|
0
|
|
|
|
|
0
|
my $root; |
1023
|
0
|
|
|
|
|
0
|
for $root (@{$roots}) { |
|
0
|
|
|
|
|
0
|
|
1024
|
0
|
|
|
|
|
0
|
$root =~ s#/\z##; |
1025
|
0
|
0
|
|
|
|
0
|
(undef, undef, my $rp) = lstat $root or next; |
1026
|
0
|
|
|
|
|
0
|
$rp &= 07777; # don't forget setuid, setgid, sticky bits |
1027
|
0
|
0
|
|
|
|
0
|
if ( -d _ ) { |
1028
|
|
|
|
|
|
|
# notabene: 0777 is for making readable in the first place, |
1029
|
|
|
|
|
|
|
# it's also intended to change it to writable in case we have |
1030
|
|
|
|
|
|
|
# to recurse in which case we are better than rm -rf for |
1031
|
|
|
|
|
|
|
# subtrees with strange permissions |
1032
|
0
|
0
|
0
|
|
|
0
|
chmod(0777, ($Is_VMS ? VMS::Filespec::fileify($root) : $root)) |
|
|
0
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
or $self->warn("Could not make directory '$root' read+writable: $!") |
1034
|
|
|
|
|
|
|
unless $safe; |
1035
|
0
|
0
|
|
|
|
0
|
if (opendir DIR, $root){ |
1036
|
0
|
|
|
|
|
0
|
@files = readdir DIR; |
1037
|
0
|
|
|
|
|
0
|
closedir DIR; |
1038
|
|
|
|
|
|
|
} else { |
1039
|
0
|
|
|
|
|
0
|
$self->warn("Could not read directory '$root': $!"); |
1040
|
0
|
|
|
|
|
0
|
@files = (); |
1041
|
|
|
|
|
|
|
} |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
# Deleting large numbers of files from VMS Files-11 filesystems |
1044
|
|
|
|
|
|
|
# is faster if done in reverse ASCIIbetical order |
1045
|
0
|
0
|
|
|
|
0
|
@files = reverse @files if $Is_VMS; |
1046
|
0
|
0
|
|
|
|
0
|
($root = VMS::Filespec::unixify($root)) =~ s#\.dir\z## if $Is_VMS; |
1047
|
0
|
|
|
|
|
0
|
@files = map("$root/$_", grep $_!~/^\.{1,2}\z/s,@files); |
1048
|
0
|
|
|
|
|
0
|
$count += $self->rmtree([@files],$verbose,$safe); |
1049
|
0
|
0
|
0
|
|
|
0
|
if ($safe && |
|
|
0
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
($Is_VMS ? !&VMS::Filespec::candelete($root) : !-w $root)) { |
1051
|
0
|
0
|
|
|
|
0
|
print "skipped '$root'\n" if $verbose; |
1052
|
0
|
|
|
|
|
0
|
next; |
1053
|
|
|
|
|
|
|
} |
1054
|
0
|
0
|
0
|
|
|
0
|
chmod 0777, $root |
1055
|
|
|
|
|
|
|
or $self->warn("Could not make directory '$root' writable: $!") |
1056
|
|
|
|
|
|
|
if $force_writable; |
1057
|
0
|
0
|
|
|
|
0
|
print "rmdir '$root'\n" if $verbose; |
1058
|
0
|
0
|
|
|
|
0
|
if (rmdir $root) { |
1059
|
0
|
|
|
|
|
0
|
++$count; |
1060
|
|
|
|
|
|
|
} |
1061
|
|
|
|
|
|
|
else { |
1062
|
0
|
|
|
|
|
0
|
$self->warn("Could not remove directory '$root': $!"); |
1063
|
0
|
0
|
|
|
|
0
|
chmod($rp, ($Is_VMS ? VMS::Filespec::fileify($root) : $root)) |
|
|
0
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
or $self->warn("and can't restore permissions to " |
1065
|
|
|
|
|
|
|
. sprintf("0%o",$rp) . "\n"); |
1066
|
|
|
|
|
|
|
} |
1067
|
|
|
|
|
|
|
} |
1068
|
|
|
|
|
|
|
else { |
1069
|
0
|
0
|
0
|
|
|
0
|
if ( $safe |
|
|
0
|
0
|
|
|
|
|
1070
|
|
|
|
|
|
|
and ($Is_VMS ? !&VMS::Filespec::candelete($root) |
1071
|
|
|
|
|
|
|
: !(-l $root || -w $root)) |
1072
|
|
|
|
|
|
|
) { |
1073
|
0
|
0
|
|
|
|
0
|
print "skipped '$root'\n" if $verbose; |
1074
|
0
|
|
|
|
|
0
|
next; |
1075
|
|
|
|
|
|
|
} |
1076
|
0
|
0
|
0
|
|
|
0
|
chmod 0666, $root |
1077
|
|
|
|
|
|
|
or $self->warn( "Could not make file '$root' writable: $!") |
1078
|
|
|
|
|
|
|
if $force_writable; |
1079
|
0
|
0
|
|
|
|
0
|
warn "unlink '$root'\n" if $verbose; |
1080
|
|
|
|
|
|
|
# delete all versions under VMS |
1081
|
0
|
|
|
|
|
0
|
for (;;) { |
1082
|
0
|
0
|
|
|
|
0
|
unless (unlink $root) { |
1083
|
0
|
|
|
|
|
0
|
$self->warn("Could not unlink file '$root': $!"); |
1084
|
0
|
0
|
|
|
|
0
|
if ($force_writable) { |
1085
|
0
|
0
|
|
|
|
0
|
chmod $rp, $root |
1086
|
|
|
|
|
|
|
or $self->warn("and can't restore permissions to " |
1087
|
|
|
|
|
|
|
. sprintf("0%o",$rp) . "\n"); |
1088
|
|
|
|
|
|
|
} |
1089
|
0
|
|
|
|
|
0
|
last; |
1090
|
|
|
|
|
|
|
} |
1091
|
0
|
|
|
|
|
0
|
++$count; |
1092
|
0
|
0
|
0
|
|
|
0
|
last unless $Is_VMS && lstat $root; |
1093
|
|
|
|
|
|
|
} |
1094
|
|
|
|
|
|
|
} |
1095
|
|
|
|
|
|
|
} |
1096
|
|
|
|
|
|
|
|
1097
|
0
|
|
|
|
|
0
|
return $count; |
1098
|
|
|
|
|
|
|
} |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
=head2 _flush_on_write |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
Title : _flush_on_write |
1104
|
|
|
|
|
|
|
Usage : $io->_flush_on_write($newval) |
1105
|
|
|
|
|
|
|
Function: Boolean flag to indicate whether to flush |
1106
|
|
|
|
|
|
|
the filehandle on writing when the end of |
1107
|
|
|
|
|
|
|
a component is finished (Sequences, Alignments, etc) |
1108
|
|
|
|
|
|
|
Args : Optional new value |
1109
|
|
|
|
|
|
|
Returns : Value of _flush_on_write |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
=cut |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
sub _flush_on_write { |
1114
|
11388
|
|
|
11388
|
|
18028
|
my ($self, $value) = @_; |
1115
|
11388
|
100
|
|
|
|
21076
|
if (defined $value) { |
1116
|
10730
|
|
|
|
|
17771
|
$self->{'_flush_on_write'} = $value; |
1117
|
|
|
|
|
|
|
} |
1118
|
11388
|
|
|
|
|
16803
|
return $self->{'_flush_on_write'}; |
1119
|
|
|
|
|
|
|
} |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
=head2 save_tempfiles |
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
Title : save_tempfiles |
1125
|
|
|
|
|
|
|
Usage : $io->save_tempfiles(1) |
1126
|
|
|
|
|
|
|
Function: Boolean flag to indicate whether to retain tempfiles/tempdir |
1127
|
|
|
|
|
|
|
Args : Value evaluating to TRUE or FALSE |
1128
|
|
|
|
|
|
|
Returns : Boolean value : 1 = save tempfiles/tempdirs, 0 = remove (default) |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
=cut |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
sub save_tempfiles { |
1133
|
34
|
|
|
34
|
1
|
50
|
my $self = shift; |
1134
|
34
|
50
|
|
|
|
65
|
if (@_) { |
1135
|
0
|
|
|
|
|
0
|
my $value = shift; |
1136
|
0
|
0
|
|
|
|
0
|
$self->{save_tempfiles} = $value ? 1 : 0; |
1137
|
|
|
|
|
|
|
} |
1138
|
34
|
|
50
|
|
|
135
|
return $self->{save_tempfiles} || 0; |
1139
|
|
|
|
|
|
|
} |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
1; |