SMBInputStream.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (C) 2006-2010 Alfresco Software Limited.
  3. *
  4. * This file is part of Alfresco
  5. *
  6. * Alfresco is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Alfresco is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package org.alfresco.jlan.client;
  20. import java.io.*;
  21. import org.alfresco.jlan.smb.SMBException;
  22. import org.alfresco.jlan.smb.SeekType;
  23. /**
  24. * SMB input stream class.
  25. *
  26. * <p>
  27. * The SMBInputStream class provides a standard InputStream interface to a remote file.
  28. *
  29. * <p>
  30. * The class may be used with other I/O stream classes such as InputStreamReader, DataInputStream
  31. * etc.
  32. *
  33. * <p>
  34. * <strong>Note:</strong> It is not necessary to use a BufferedInputStream or BufferedReader class
  35. * with the SMBInputStream as the underlying network connection will usually buffer 4Kb of data, up
  36. * to a maximum of 64Kb.
  37. *
  38. *
  39. * <p>
  40. * Example use of the SMBInputStream class
  41. *
  42. * <p>
  43. * <code>PCShare shr = new PCShare ( "\\\\TEST\\C\\");<br>
  44. * DiskSession sess = SessionFactory.OpenDisk ( shr);<br>
  45. * SMBInputStream in = sess.OpenInputStream ( "DATAFILE.IN", AccessMode.ReadOnly);<br>
  46. * LineNumberReader lnRdr = new LineNumberReader ( new InputStreamReader ( in));<br>
  47. * String inRec = null;<br>
  48. * while (( inRec = lnRdr.readLine ()) != null)<br>
  49. * &nbsp;&nbsp;System.out.println ( lnRdr.getLineNumber () + ": " + inRec);<br>
  50. * in.close ();</code>
  51. *
  52. * @author gkspencer
  53. */
  54. public class SMBInputStream extends java.io.InputStream {
  55. // SMB file that this stream is associated with.
  56. private SMBFile m_file;
  57. // Marked position and read limit
  58. private long m_markPos;
  59. private int m_readLimit;
  60. /**
  61. * Construct an SMB input stream attached to the specified SMB file.
  62. *
  63. * @param sfile SMBFile that this input stream is associated with.
  64. */
  65. protected SMBInputStream(SMBFile sfile) {
  66. m_file = sfile;
  67. }
  68. /**
  69. * Return the number of bytes that can be read from this input stream without blocking.
  70. *
  71. * @return Number of bytes that can be read without the input stream blocking.
  72. * @exception java.io.IOException If an I/O error occurs.
  73. */
  74. public int available()
  75. throws java.io.IOException {
  76. return m_file.Available();
  77. }
  78. /**
  79. * Close the input stream and release any system resources associated with the stream.
  80. *
  81. * @exception java.io.IOException If an I/O error occurs.
  82. */
  83. public void close()
  84. throws java.io.IOException {
  85. // Close the remote file
  86. try {
  87. m_file.Close();
  88. }
  89. catch (SMBException ex) {
  90. throw new IOException(ex.getErrorText());
  91. }
  92. }
  93. /**
  94. * Return a reference to the associated SMBFile object.
  95. *
  96. * @return SMBFile associated with this input stream.
  97. */
  98. public final SMBFile File() {
  99. return m_file;
  100. }
  101. /**
  102. * Read a byte of data from the input stream.
  103. *
  104. * @return The next byte of data, or -1 if the end of file has been reached.
  105. * @exception java.io.IOException If an I/O error occurs.
  106. */
  107. public int read()
  108. throws java.io.IOException {
  109. // Read a byte from the SMB file
  110. try {
  111. byte[] buf = new byte[2];
  112. if ( m_file.Read(buf, 1, 0) == 1)
  113. return (int) buf[0];
  114. return -1;
  115. }
  116. catch (SMBException ex) {
  117. throw new IOException(ex.getErrorText());
  118. }
  119. }
  120. /**
  121. * Read a block of bytes from the input stream.
  122. *
  123. * @param buf The buffer to read the data into.
  124. * @param off The start offset to place the received data.
  125. * @param len The maximum number of bytes to read.
  126. * @return The number of bytes read into the buffer, or -1 if the end of file has been reached.
  127. * @exception java.io.IOException If an I/O error occurs.
  128. */
  129. public int read(byte[] buf, int off, int len)
  130. throws java.io.IOException {
  131. // Read a block of bytes into the user buffer
  132. try {
  133. int rdlen = m_file.Read(buf, len, off);
  134. if ( rdlen > 0)
  135. return rdlen;
  136. return -1;
  137. }
  138. catch (SMBException ex) {
  139. throw new IOException(ex.getErrorText());
  140. }
  141. }
  142. /**
  143. * Skip over a number of bytes in the input stream.
  144. *
  145. * @param n Number of bytes to skip.
  146. * @return The actual number of bytes skipped.
  147. * @exception java.io.IOException If an I/O error occurs.
  148. */
  149. public int skip(int n)
  150. throws java.io.IOException {
  151. // Seek to the new file read position
  152. long curPos = m_file.getReadPosition();
  153. long newPos = curPos;
  154. try {
  155. newPos = m_file.Seek((long) n, SeekType.CurrentPos);
  156. }
  157. catch (SMBException ex) {
  158. throw new IOException("skip error, " + ex.toString());
  159. }
  160. // Return the number of bytes skipped
  161. return (int) (newPos - curPos);
  162. }
  163. /**
  164. * Mark the current file position
  165. *
  166. * @param readLimit int
  167. */
  168. public synchronized void mark(int readLimit) {
  169. // Save the current read position and the read limit
  170. m_markPos = m_file.getReadPosition();
  171. m_readLimit = readLimit;
  172. }
  173. /**
  174. * Determine if mark is supported
  175. *
  176. * @return boolean
  177. */
  178. public boolean markSupported() {
  179. return true;
  180. }
  181. /**
  182. * Reset the file pointer to the previous marked position
  183. *
  184. * @exception IOException
  185. */
  186. public synchronized void reset()
  187. throws IOException {
  188. // Check if the current read position is past the read limit
  189. if ( m_file.getReadPosition() > (m_markPos + m_readLimit))
  190. throw new IOException("Position past read limit");
  191. // Reset the read position to the marked position
  192. try {
  193. m_file.Seek(m_markPos, SeekType.StartOfFile);
  194. }
  195. catch (SMBException ex) {
  196. throw new IOException(ex.getErrorText());
  197. }
  198. }
  199. }