0
|
1 =head1 LICENSE
|
|
2
|
|
3 Copyright (c) 1999-2012 The European Bioinformatics Institute and
|
|
4 Genome Research Limited. All rights reserved.
|
|
5
|
|
6 This software is distributed under a modified Apache license.
|
|
7 For license details, please see
|
|
8
|
|
9 http://www.ensembl.org/info/about/code_licence.html
|
|
10
|
|
11 =head1 CONTACT
|
|
12
|
|
13 Please email comments or questions to the public Ensembl
|
|
14 developers list at <dev@ensembl.org>.
|
|
15
|
|
16 Questions may also be sent to the Ensembl help desk at
|
|
17 <helpdesk@ensembl.org>.
|
|
18
|
|
19 =cut
|
|
20
|
|
21 =head1 NAME
|
|
22
|
|
23 Bio::EnsEMBL::DBFile::FileAdaptor - Base Adaptor for direct file access
|
|
24
|
|
25 =head1 DESCRIPTION
|
|
26
|
|
27 Basic wrapper class to provide access to file based data.
|
|
28
|
|
29 This is primarily aimed at indexed Collection(.col) files which are optimised for Slice
|
|
30 based queries. Collections store fixed width width/windowed data as BLOBS. This makes
|
|
31 it possible to seek to the a required location given slice coordinate and read the only
|
|
32 the required amount of data covering the slice.
|
|
33
|
|
34 Currently only works as hybrid DBAdaptor e.g. ResultFeatureAdaptor which inherits both from
|
|
35 here and BaseFeatureAdaptor.
|
|
36
|
|
37 =cut
|
|
38
|
|
39
|
|
40
|
|
41 package Bio::EnsEMBL::DBFile::FileAdaptor;
|
|
42
|
|
43 use Bio::EnsEMBL::Utils::Exception qw(throw warning deprecate);
|
|
44 use strict;
|
|
45 use warnings;
|
|
46
|
|
47
|
|
48 =head2 get_filehandle
|
|
49
|
|
50 Arg[1] : string - filepath
|
|
51 Arg[2] : HASHREF - Optional params, see open_file
|
|
52 Example : my $fh = $self->get_filehandle($filepath, 1);
|
|
53 Description: Gets and caches a simple file handle.
|
|
54 Returntype : GLOB/undef - filehandle
|
|
55 Exceptions : warns if cache entry exists but is not defined
|
|
56 Caller : general
|
|
57 Status : at risk
|
|
58
|
|
59 =cut
|
|
60
|
|
61 sub get_filehandle{
|
|
62 my ($self, $filepath, $params_hash) = @_;
|
|
63
|
|
64 my $file_op = '<';
|
|
65
|
|
66 if(exists $params_hash->{-file_operator}){
|
|
67 $file_op = $params_hash->{-file_operator};
|
|
68 }else{
|
|
69 $params_hash->{-file_operator} = $file_op;
|
|
70 }
|
|
71
|
|
72 if(! exists $self->{file_cache}{$filepath}{filehandle}){
|
|
73 my $fh = $self->Bio::EnsEMBL::DBFile::FileAdaptor::open_file($filepath, $params_hash);
|
|
74
|
|
75 if(defined $fh){
|
|
76 $self->{file_cache}{$filepath}{filehandle} = $fh;
|
|
77 #$self->initialise_filehandle($filepath) if $self->can('initialise_filehandle');
|
|
78 $self->initialise_filehandle($filepath) if($file_op eq '<');
|
|
79 }
|
|
80 }
|
|
81 elsif(! defined $self->{file_cache}{$filepath}{filehandle}){
|
|
82 #This maybe one of several read/seek errors which will have already been warned
|
|
83 warn "Encountered and error with file handle for $filepath\n";
|
|
84 }
|
|
85 #else
|
|
86 # check against cache file op
|
|
87 # to make sure we aren't trying to open an already open fh with a different operator
|
|
88
|
|
89
|
|
90 return $self->{file_cache}{$filepath}{filehandle};
|
|
91 }
|
|
92
|
|
93
|
|
94 =head2 open_file
|
|
95
|
|
96 Arg[1] : string - filepath
|
|
97 Arg[2] : HASHREF - Optional params:
|
|
98 -binmode => 0|1, # Boolean i.e. treat file as binary
|
|
99 -file_operator => '>' # Default is '<'
|
|
100 #-perms_octal => # Requires FileHandle
|
|
101 Example : my $fh = $self->open_file($filepath, {-binmode = > 1, -file_operator => '>'});
|
|
102 Description: Opens a file for reading or writing.
|
|
103 Returntype : GLOB/undef - filehandle
|
|
104 Exceptions : warns if file open fails
|
|
105 warns if file operator unsupported
|
|
106 warns if failed to set binmode
|
|
107 Caller : general
|
|
108 Status : at risk
|
|
109
|
|
110 =cut
|
|
111
|
|
112 sub open_file{
|
|
113 my ($self, $filepath, $params_hash) = @_;
|
|
114
|
|
115 #Validate params_hash?
|
|
116 #rearrange? Will not warn/throw for invalid keys?
|
|
117 #perms octal, requires FileHandle? See EFGUtils::open_file
|
|
118
|
|
119
|
|
120
|
|
121 my $file_op = $params_hash->{-file_operator} || '<';
|
|
122
|
|
123 if(($file_op ne '<') &&
|
|
124 ($file_op ne '>') &&
|
|
125 ($file_op ne '>>')){
|
|
126 throw("Cannot perform open with unsupported operator:\t${file_op}${filepath}");
|
|
127 }
|
|
128
|
|
129 my $fh;
|
|
130 my $success = open($fh, "${file_op}${filepath}");
|
|
131 #$fh will be still be GLOB on fail
|
|
132
|
|
133 #These warn instead of throw/die to allow
|
|
134 #open_file to be used to test a file
|
|
135 #this prevents throws/die when an attempting to access an absent file (good for webcode)
|
|
136 #could alternatively change to throw/die and eval where required
|
|
137 #prevents need to catch everywhere else and potential double reporting of error
|
|
138
|
|
139 if(! $success){
|
|
140 #undef $fh;
|
|
141 throw("Failed to open:\t$filepath\n$!\n");
|
|
142 }
|
|
143 elsif($params_hash->{-binmode}){
|
|
144 $success = binmode $fh;
|
|
145
|
|
146 if(! $success){
|
|
147 throw("Failed to set binmode:\t$filepath\n$!");
|
|
148 #undef $fh;
|
|
149 }
|
|
150 }
|
|
151
|
|
152 return $fh;
|
|
153 }
|
|
154
|
|
155
|
|
156 =head2 validate_file_length
|
|
157
|
|
158 Arg[1] : string - filepath
|
|
159 Arg[2] : int - expected length in bytes
|
|
160 Example : $self->validate_file_length($filepath, $expected_length);
|
|
161 Description: Utility method which can be used during file creation
|
|
162 Returntype : None
|
|
163 Exceptions : warns if file open fails
|
|
164 throws if file is not expected length
|
|
165 Caller : general
|
|
166 Status : at risk - change to seek to accounts for 'logical characters'
|
|
167
|
|
168 =cut
|
|
169
|
|
170 sub validate_file_length{
|
|
171 my ($self, $filepath, $expected_length, $binmode) = @_;
|
|
172
|
|
173 #Currently not using cache as we rarely want to
|
|
174 #use the file handle afterwards
|
|
175
|
|
176
|
|
177 #THIS WAS USING EFGUtils::open_file imported in the Collector::ResultFeature!!!!
|
|
178 #which is just a sub not a class method, and is in a parallel inheritance path
|
|
179 #No warnings about redefining method :(
|
|
180 #Force use of FileAdaptor::open_file
|
|
181
|
|
182 my $fh = $self->Bio::EnsEMBL::DBFile::FileAdaptor::open_file($filepath, {-binmode => $binmode});
|
|
183
|
|
184
|
|
185 #sysseek always returns length in bytes, change to seek which
|
|
186 #uses logical characters i.e. actual encoding?
|
|
187 #Does seek use bytes in binmode and chars in non-binmode?
|
|
188
|
|
189 my $seeked_bytes = sysseek($fh, 0, 2);# 2 is SEEK_END
|
|
190 #There is no systell function. Use sysseek(FH, 0, 1) for that.
|
|
191
|
|
192 if($seeked_bytes < $expected_length){
|
|
193 throw("File is shorter($seeked_bytes) than expected($expected_length):\t$filepath\n");
|
|
194 }
|
|
195 elsif($seeked_bytes > $expected_length){
|
|
196 throw("File is longer($seeked_bytes) than expected($expected_length):\t$filepath\n");
|
|
197 }
|
|
198
|
|
199 return;
|
|
200 }
|
|
201
|
|
202
|
|
203
|
|
204
|
|
205
|
|
206 ### STUBB/TEMPLATE METHODS ###
|
|
207 #
|
|
208 # If required hese should be over-ridden in the
|
|
209 # descendant FileAdaptor e.g. CollectionAdaptor
|
|
210 # Listed here rather for visibility (rather than
|
|
211 # using 'can')
|
|
212
|
|
213
|
|
214 sub initialise_filehandle{
|
|
215 return;
|
|
216 }
|
|
217
|
|
218
|
|
219
|
|
220 1;
|