Source code: org/fudaa/dodico/fortran/FortranBinaryInputStream.java
1 /*
2 * @file FortranBinaryInputStream.java
3 * @creation 1998-08-19
4 * @modification $Date: 2002/11/25 09:59:25 $
5 * @license GNU General Public License 2
6 * @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne
7 * @mail devel@fudaa.org
8 */
9
10 package org.fudaa.dodico.fortran;
11
12 import java.io.*;
13 import java.util.*;
14
15 /**
16 * Une classe facilitant la lecture de fichiers binaires écrits par Fortran
17 * L'équivalence d'intructions entre Java et Fortran se fera de la manière
18 * suivante :<BR><PRE>
19 * (en considérant i=integer/int, f=real/float, d=double precision/double et
20 * s=character*()/String)
21 * 1) Pour un fichier à acces séquentiel :
22 * Fortran
23 * open (unit=10,file='fichier.bin',access='sequentiel',form='unformatted')
24 * read (unit=10) <i>,<f>,<d>,<s>
25 * ...
26 * close (unit=10)
27 * Java
28 * FortranBinaryInputStream in=
29 * new FortranBinaryInputStream(new FileInputStream("fichier.bin"),true);
30 * in.readRecord();
31 * i=in.readInteger();
32 * f=in.readReal();
33 * d=in.readDoublePrecision();
34 * s=in.readCharacter(s.length());
35 * ...
36 * in.close();
37 * 2) Pour un fichier à acces direct :
38 * Fortran
39 * open (unit=10,file='fichier.bin',access='direct',recl=30,form='unformatted')
40 * read (unit=10,rec=1) <i>,<f>,<d>,<s>
41 * ...
42 * close (unit=10)
43 * Java
44 * FortranBinaryInputStream in=
45 * new FortranBinaryInputStream(new FileInputStream("fichier.bin"),false);
46 * in.setRecordLength(30);
47 * in.readRecord();
48 * i=in.readInteger();
49 * f=in.readReal();
50 * d=in.readDoublePrecision();
51 * s=in.readCharacter(s.length());
52 * ...
53 * in.close();
54 * </PRE>
55 *
56 * @version $Revision: 1.9 $ $Date: 2002/11/25 09:59:25 $ by $Author: deniger $
57 * @author Bertrand Marchand
58 */
59 public class FortranBinaryInputStream extends NativeBinaryInputStream {
60 // private NativeBinaryInputStream bufStream_;
61 // private ByteArrayInputStream arrayStream_;
62 private boolean sequential_;
63 private int recordLength_;
64 private long currentPos_;
65 private long nextPos_;
66
67 /**
68 * Création en précisant si le fichier binaire est à access séquentiel ou non.
69 * Si sequentiel, alors certaines donnees ( generees par la meme instruction write
70 * de fortran) sont entourees par 4 octets qui correspondent a la longueur
71 * de l'enregistrement. La variable systeme ("os.arch") permet de déterminer
72 * l'architecture a utiliser.
73 * @param _in InputStream
74 * @param _sequential <B>true</B> le fichier est binaire à accès
75 * <I>Sequential</I>. <B>false</B> le fichier est binaire à accès <I>Direct</I>
76 */
77 public FortranBinaryInputStream(InputStream _in, boolean _sequential)
78 throws IOException{
79 this(_in,_sequential,System.getProperty("os.arch"));
80
81 }
82
83 /**
84 * Il est possible de definir l'architecture intel ( little indian) ou sparc
85 * (big indian).
86 * @param _in InputStream.
87 * @param _sequential <B>true</B> le fichier est binaire à accès
88 * <I>Sequential</I>. <B>false</B> le fichier est binaire à accès
89 * <I>Direct</I>
90 * @param _architecture "sparc" pour le big endian et "X86" pour le little
91 * endian. Utiliser les identifiant de NativeBinaryInputStream
92 * @see org.fudaa.dodico.fortran.NativeBinaryInputStream
93 */
94 public FortranBinaryInputStream(InputStream _in, boolean _sequential, String _architectureID)
95 throws IOException{
96 super(_in,_architectureID);
97 //arrayStream_ =new ByteArrayInputStream();
98 //bufStream_ =new NativeBinaryInputStream(arrayStream_,
99 // System.getProperty("os.arch"));
100 sequential_ =_sequential;
101 recordLength_=0;
102 nextPos_ =0;
103 currentPos_ =nextPos_;
104 }
105
106 /**
107 * ATTENTION Different du cas acces direct.
108 * Renvoie la taille de l'enregistrement lu par le flux.
109 */
110 public int getSequentialRecordLength()
111 {
112 return recordLength_;
113 }
114
115 /**
116 * Affectation de la longueur des enregistrements (pour les fichiers à accès
117 * <I>Direct</I>
118 * @param _length Longueur d'enregistrement en longworld
119 * (1 longworld=4 octets)
120 */
121 public void setRecordLength(int _length) { recordLength_=_length*4; }
122
123 /**
124 * Retourne la longueur des enregistrements (pour les fichiers à accès
125 * <I>Direct</I>
126 * @return Longueur d'enregistrement en longworld (1 longworld=4 octets)
127 */
128 public int getRecordLength() { return recordLength_/4; }
129
130 /**
131 * Lecture d'un champ chaine de caractères "<I>character</I>" Fortran
132 * @param _lgString Longueur de la chaine à lire
133 * @return String correspondant à la chaine de caractères
134 */
135 public String readCharacter(int _lgString) throws IOException {
136 byte[] buf=new byte[_lgString];
137 currentPos_+=_lgString;
138 read(buf);
139 return new String(buf);
140 }
141
142 // public void writeCharacter(char[] _c) {
143 // }
144 // public void writeCharacter(char _c) {
145 // }
146
147 /**
148 * Lecture d'un champ entier "<I>integer</I>" Fortran
149 * @return int correspondant au integer
150 */
151 public int readInteger() throws IOException {
152 currentPos_+=4;
153 return super.readInt_32();
154 }
155
156 /**
157 * Lecture d'un champ réel "<I>real</I>" Fortran
158 * @return float correspondant au real
159 */
160 public float readReal() throws IOException {
161 currentPos_+=4;
162 return super.readFloat_32();
163 }
164
165 /**
166 * Lecture d'un champ réel en double précision "<I>double precision</I>"
167 * Fortran
168 * @return double correspondant au double precision
169 */
170 public double readDoublePrecision() throws IOException {
171 currentPos_+=8;
172 return super.readFloat_64();
173 }
174
175 /**
176 * Redefinition de la methode (changement: la position courante est
177 * geree).
178 */
179 public byte readInt_8() throws IOException
180 {
181 currentPos_+=1;
182 return super.readInt_8();
183 }
184
185 /**
186 * Redefinition de la methode (changement: la position courante est
187 * geree).
188 */
189 public short readUInt_8() throws IOException
190 {
191 currentPos_+=1;
192 return super.readUInt_8();
193 }
194
195 /**
196 * Redefinition de la methode (changement: la position courante est
197 * geree).
198 */
199 public short readInt_16() throws IOException
200 {
201 currentPos_+=2;
202 return super.readInt_16();
203 }
204
205 /**
206 * Redefinition de la methode (changement: la position courante est
207 * geree).
208 */
209 public int readUInt_16() throws IOException
210 {
211 currentPos_+=2;
212 return super.readUInt_16();
213 }
214
215 /**
216 * Redefinition de la methode (changement: la position courante est
217 * geree).
218 */
219 public int readInt_32() throws IOException
220 {
221 currentPos_+=4;
222 return super.readInt_32();
223 }
224
225 /**
226 * Redefinition de la methode (changement: la position courante est
227 * geree).
228 */
229 public long readUInt_32() throws IOException
230 {
231 currentPos_+=4;
232 return super.readUInt_32();
233 }
234
235 public long readInt_64() throws IOException
236 {
237 currentPos_+=8;
238 return super.readInt_64();
239 }
240
241 public float readFloat_32() throws IOException
242 {
243 currentPos_+=4;
244 return super.readFloat_32();
245 }
246
247 public double readFloat_64() throws IOException
248 {
249 currentPos_+=8;
250 return super.readFloat_64();
251 }
252
253 /**
254 * Renvoie en nb d'octets la position courante.
255 */
256 public long positionCourante()
257 {
258 return currentPos_;
259 }
260
261
262
263
264 /**
265 * Lecture des champs de l'enregistrement. L'enregistrement doit etre lu
266 * avant la lecture des champs.
267 * Un enregistrement correspond à une instruction READ du Fortran
268 */
269 public void readRecord() throws IOException {
270 skip(nextPos_-currentPos_);
271 currentPos_=nextPos_;
272
273 if (sequential_) {
274 recordLength_=readInt_32();
275 nextPos_+=(long)recordLength_+8;
276 }
277 else {
278 nextPos_+=(long)recordLength_;
279 }
280 }
281 }