1 // JRclient library - client interface to Rserve, see http://www.rosuda.org/Rserve/
2 // Copyright (C) 2003 Simon Urbanek
3 // --- for licensing information see LICENSE file in the original JRclient distribution ---
5 // RFileOutputStream.java
7 // Created by Simon Urbanek on Wed Oct 22 2003.
10 package org.rosuda.REngine.Rserve;
13 import org.rosuda.REngine.*;
14 import org.rosuda.REngine.Rserve.protocol.*;
16 /** <b>RFileOutputStream</b> is an {@link OutputStream} to transfer files
17 from the client to <b>Rserve</b> server. It is used very much like
18 a {@link FileOutputStream}. Currently mark and seek is not supported.
19 The current implementation is also "one-shot" only, that means the file
20 can be written only once.
24 public class RFileOutputStream extends OutputStream {
25 /** RTalk class to use for communication with the Rserve */
27 /** set to <code>true</code> when {@link #close} was called.
28 Any subsequent read requests on closed stream result in an
29 {@link IOException} or error result */
32 /** tries to create a file on the R server, using specified {@link RTalk} object
33 and filename. Be aware that the filename has to be specified in host
34 format (which is usually unix). In general you should not use directories
35 since Rserve provides an own directory for every connection. Future Rserve
36 servers may even strip all directory navigation characters for security
37 purposes. Therefore only filenames without path specification are considered
38 valid, the behavior in respect to absolute paths in filenames is undefined.
39 @param rti RTalk object for communication with Rserve
40 @param fb filename of the file to create (existing file will be overwritten)
42 RFileOutputStream(RTalk rti, String fn) throws IOException {
44 RPacket rp=rt.request(RTalk.CMD_createFile,fn);
45 if (rp==null || !rp.isOk())
46 throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
50 /** writes one byte to the file. This function should be avoided, since
51 {@link RFileOutputStream} provides no buffering. This means that each
52 call to this function leads to a complete packet exchange between
53 the server and the client. Use {@link #write(byte[])} instead
54 whenever possible. In fact this function calls <code>write(b,0,1)</code>.
55 @param b byte to write
57 public void write(int b) throws IOException {
58 byte[] ba=new byte[1];
62 /** writes the content of b into the file. This methods is equivalent to calling <code>write(b,0,b.length)</code>.
63 @param b content to write
65 public void write(byte b[]) throws IOException {
69 /** Writes specified number of bytes to the remote file.
70 @param b buffer containing the bytes to write
71 @param off offset where to start
72 @param len number of bytes to write
74 public void write(byte[] b, int off, int len) throws IOException {
75 if (closed) throw new IOException("File is not open");
77 boolean isLarge=(len>0xfffff0);
78 byte[] hdr=RTalk.newHdr(RTalk.DT_BYTESTREAM,len);
79 RPacket rp=rt.request(RTalk.CMD_writeFile,hdr,b,off,len);
80 if (rp==null || !rp.isOk())
81 throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
84 /** close stream - is not related to the actual RConnection, calling
85 close does not close the RConnection.
87 public void close() throws IOException {
88 RPacket rp=rt.request(RTalk.CMD_closeFile,(byte[])null);
89 if (rp==null || !rp.isOk())
90 throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
94 /** currently (Rserve 0.3) there is no way to force flush on the remote side, hence this function is noop. Future versions of Rserve may support this feature though. At any rate, it is safe to call it. */