mev-4.0.01/source/org/tigr/microarray/mev/r/RFileInputStream.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 package org.tigr.microarray.mev.r;
2 26 Feb 07 jari 2
2 26 Feb 07 jari 3 import java.io.*;
2 26 Feb 07 jari 4
2 26 Feb 07 jari 5 /** <b>RFileInputStream</b> is an {@link InputStream} to transfer files
2 26 Feb 07 jari 6     from <b>Rserve</b> server to the client. It is used very much like
2 26 Feb 07 jari 7     a {@link FileInputStream}. Currently mark and seek is not supported.
2 26 Feb 07 jari 8     The current implementation is also "one-shot" only, that means the file
2 26 Feb 07 jari 9     can be read only once.
2 26 Feb 07 jari 10     @version $Id$
2 26 Feb 07 jari 11 */
2 26 Feb 07 jari 12 public class RFileInputStream extends InputStream {
2 26 Feb 07 jari 13     /** Rtalk class to use for communication with the Rserve */
2 26 Feb 07 jari 14     Rtalk rt;
2 26 Feb 07 jari 15     /** set to <code>true</code> when {@link #close} was called.
2 26 Feb 07 jari 16   Any subsequent read requests on closed stream  result in an 
2 26 Feb 07 jari 17   {@link IOException} or error result */
2 26 Feb 07 jari 18     boolean closed;
2 26 Feb 07 jari 19     /** set to <code>true</code> once EOF is reached - or more specifically
2 26 Feb 07 jari 20   the first time remore fread returns OK and 0 bytes */
2 26 Feb 07 jari 21     boolean eof;
2 26 Feb 07 jari 22
2 26 Feb 07 jari 23     /** tries to open file on the R server, using specified {@link Rtalk} object
2 26 Feb 07 jari 24   and filename. Be aware that the filename has to be specified in host
2 26 Feb 07 jari 25   format (which is usually unix). In general you should not use directories
2 26 Feb 07 jari 26   since Rserve provides an own directory for every connection. Future Rserve
2 26 Feb 07 jari 27   servers may even strip all directory navigation characters for security
2 26 Feb 07 jari 28   purposes. Therefore only filenames without path specification are considered
2 26 Feb 07 jari 29   valid, the behavior in respect to absolute paths in filenames is undefined. */
2 26 Feb 07 jari 30     RFileInputStream(Rtalk rti, String fn) throws IOException {
2 26 Feb 07 jari 31   rt=rti;
2 26 Feb 07 jari 32   Rpacket rp=rt.request(Rtalk.CMD_openFile,fn);
2 26 Feb 07 jari 33   if (rp==null || !rp.isOk())
2 26 Feb 07 jari 34       throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
2 26 Feb 07 jari 35   closed=false; eof=false;
2 26 Feb 07 jari 36     }
2 26 Feb 07 jari 37
2 26 Feb 07 jari 38     /** reads one byte from the file. This function should be avoided, since
2 26 Feb 07 jari 39   {@link RFileInputStream} provides no buffering. This means that each
2 26 Feb 07 jari 40   call to this function leads to a complete packet exchange between
2 26 Feb 07 jari 41   the server and the client. Use {@link #read(byte[],int,int)} instead
2 26 Feb 07 jari 42   whenever possible. In fact this function calls <code>#read(b,0,1)</code>.
2 26 Feb 07 jari 43   @return -1 on any failure, or the acquired byte (0..255) on success */
2 26 Feb 07 jari 44     public int read() throws IOException {
2 26 Feb 07 jari 45   byte[] b=new byte[1];
2 26 Feb 07 jari 46   if (read(b,0,1)<1) return -1;
2 26 Feb 07 jari 47   return b[0];
2 26 Feb 07 jari 48     }
2 26 Feb 07 jari 49
2 26 Feb 07 jari 50     /** Reads specified number of bytes (or less) from the remote file.
2 26 Feb 07 jari 51   @param b buffer to store the read bytes
2 26 Feb 07 jari 52   @param off offset where to strat filling the buffer
2 26 Feb 07 jari 53   @param len maximal number of bytes to read
2 26 Feb 07 jari 54   @return number of bytes read or -1 if EOF reached
2 26 Feb 07 jari 55     */
2 26 Feb 07 jari 56     public int read(byte[] b, int off, int len) throws IOException {
2 26 Feb 07 jari 57   if (closed) throw new IOException("File is not open");
2 26 Feb 07 jari 58   if (eof) return -1;
2 26 Feb 07 jari 59   Rpacket rp=rt.request(Rtalk.CMD_readFile,len);
2 26 Feb 07 jari 60   if (rp==null || !rp.isOk())
2 26 Feb 07 jari 61       throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
2 26 Feb 07 jari 62   byte[] rd=rp.getCont();
2 26 Feb 07 jari 63   if (rd==null) {
2 26 Feb 07 jari 64       eof=true;
2 26 Feb 07 jari 65       return -1;
2 26 Feb 07 jari 66   };
2 26 Feb 07 jari 67   int i=0;
2 26 Feb 07 jari 68   while(i<rd.length) { b[off+i]=rd[i]; i++; };
2 26 Feb 07 jari 69   return rd.length;
2 26 Feb 07 jari 70     }
2 26 Feb 07 jari 71
2 26 Feb 07 jari 72     /** close stream - is not related to the actual Rconnection, calling
2 26 Feb 07 jari 73   close does not close the Rconnection
2 26 Feb 07 jari 74     */
2 26 Feb 07 jari 75     public void close() throws IOException {
2 26 Feb 07 jari 76   Rpacket rp=rt.request(Rtalk.CMD_closeFile,(byte[])null);
2 26 Feb 07 jari 77   if (rp==null || !rp.isOk())
2 26 Feb 07 jari 78       throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
2 26 Feb 07 jari 79   closed=true;
2 26 Feb 07 jari 80     }
2 26 Feb 07 jari 81 }