SMBFile.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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.client.info.FileInfo;
  22. import org.alfresco.jlan.smb.SMBDate;
  23. import org.alfresco.jlan.smb.SMBException;
  24. import org.alfresco.jlan.smb.SMBStatus;
  25. /**
  26. * SMB file class.
  27. *
  28. * <p>This is an abstract class that defines the standard SMB file methods.
  29. *
  30. * @author gkspencer
  31. */
  32. public abstract class SMBFile {
  33. // Various file state flags.
  34. public static final int EndOfFile = 0x0001;
  35. public static final int Closed = 0x0002;
  36. // Session that this file is associated with
  37. protected Session m_sess;
  38. // File information
  39. private FileInfo m_info;
  40. // File identifier, allocated by the remote file server
  41. protected int m_FID;
  42. // SMB packets for data send/receive
  43. protected SMBPacket m_rxpkt = null;
  44. protected SMBPacket m_txpkt = null;
  45. // Read/write position within the file
  46. protected long m_rxpos = 0;
  47. protected long m_txpos = 0;
  48. // Current offset within the receive packet, current receive packet length.
  49. protected int m_rxoffset = 0;
  50. protected int m_rxlen = 0;
  51. // Current offset within the transmit packet, current transmit data length
  52. protected int m_txoffset = 0;
  53. protected int m_txlen;
  54. // File state flags
  55. private int m_flags = 0;
  56. /**
  57. * Construct an SMBFile on the specified SMB session.
  58. *
  59. * @param sess SMB session that this file is associated with.
  60. * @param finfo File information for this file.
  61. * @param fid File identifier, allocated when the file was opened.
  62. */
  63. protected SMBFile(Session sess, FileInfo finfo, int fid) {
  64. m_sess = sess;
  65. m_info = finfo;
  66. m_FID = fid;
  67. // Initialize the file write position using the current file size
  68. m_txpos = getFileSize();
  69. }
  70. /**
  71. * Check if the end of file has been reached.
  72. *
  73. * @return true if end of file has been reached, else false.
  74. */
  75. public final boolean atEndOfFile() {
  76. return (m_flags & EndOfFile) != 0 ? true : false;
  77. }
  78. /**
  79. * Clear the end of file flag
  80. */
  81. public final void clearEndOfFile() {
  82. if ( atEndOfFile())
  83. m_flags -= EndOfFile;
  84. }
  85. /**
  86. * Return the number of bytes that are available for reading without blocking the input stream.
  87. *
  88. * @return Number of bytes available for read without blocking the input stream.
  89. */
  90. public final int Available() {
  91. return m_rxlen;
  92. }
  93. /**
  94. * Close the remote file.
  95. *
  96. * @param wrDateTime Set the last write date/time, or null to let the server set the date/time
  97. * @exception java.io.IOException If an I/O error occurs
  98. * @exception SMBException If an SMB level error occurs
  99. */
  100. public abstract void Close(SMBDate wrDateTime)
  101. throws java.io.IOException, SMBException;
  102. /**
  103. * Close the remote file, let the remote server set the last write date/time
  104. *
  105. * @exception java.io.IOException If an I/O error occurs
  106. * @exception SMBException If an SMB level error occurs
  107. */
  108. public final void Close()
  109. throws java.io.IOException, SMBException {
  110. // Do not specify the last write date/time so the server will set it for us
  111. Close(null);
  112. }
  113. /**
  114. * Finalize, object destruction.
  115. */
  116. protected void finalize() {
  117. // Close the file, if not already closed
  118. if ( !isClosed()) {
  119. try {
  120. Close();
  121. }
  122. catch (SMBException ex) {
  123. }
  124. catch (java.io.IOException ex) {
  125. }
  126. }
  127. }
  128. /**
  129. * Flush any buffered data for this file.
  130. *
  131. * @exception java.io.IOException If an I/O error occurs
  132. * @exception SMBException If an SMB level error occurs
  133. */
  134. public abstract void Flush()
  135. throws java.io.IOException, SMBException;
  136. /**
  137. * Return the file attributes
  138. *
  139. * @return int
  140. */
  141. public final int getAttributes() {
  142. return m_info.getFileAttributes();
  143. }
  144. /**
  145. * Get the file name string.
  146. *
  147. * @return File name string.
  148. */
  149. public final String getFileName() {
  150. return m_info.getFileName();
  151. }
  152. /**
  153. * Get the file path string.
  154. *
  155. * @return File path string.
  156. */
  157. public final String getFilePath() {
  158. return m_info.getPath();
  159. }
  160. /**
  161. * Get the file size, in bytes.
  162. *
  163. * @return File size in bytes.
  164. */
  165. public final long getFileSize() {
  166. return m_info.getSize();
  167. }
  168. /**
  169. * Return the file id
  170. *
  171. * @return int
  172. */
  173. public final int getFileId() {
  174. return m_FID;
  175. }
  176. /**
  177. * Get the session that this file is associated with.
  178. *
  179. * @return SMBSession that this file is associated with.
  180. */
  181. protected final Session getSession() {
  182. return m_sess;
  183. }
  184. /**
  185. * Return the current file read position
  186. *
  187. * @return long
  188. */
  189. public final long getReadPosition() {
  190. return m_rxpos;
  191. }
  192. /**
  193. * Return the current write position
  194. *
  195. * @return long
  196. */
  197. public final long getWritePosition() {
  198. return m_txpos;
  199. }
  200. /**
  201. * Check if the file has been closed.
  202. *
  203. * @return true if the file has been closed, else false.
  204. */
  205. public final boolean isClosed() {
  206. return (m_flags & Closed) != 0 ? true : false;
  207. }
  208. /**
  209. * Determine if this file is a directory
  210. *
  211. * @return boolean
  212. */
  213. public final boolean isDirectory() {
  214. return m_info.isDirectory();
  215. }
  216. /**
  217. * Determine if this file is hidden
  218. *
  219. * @return boolean
  220. */
  221. public final boolean isHidden() {
  222. return m_info.isHidden();
  223. }
  224. /**
  225. * Determine if this file is read-only
  226. *
  227. * @return boolean
  228. */
  229. public final boolean isReadOnly() {
  230. return m_info.isReadOnly();
  231. }
  232. /**
  233. * Determine if this file is a system file
  234. *
  235. * @return boolean
  236. */
  237. public final boolean isSystem() {
  238. return m_info.isSystem();
  239. }
  240. /**
  241. * Read a block of data from the file.
  242. *
  243. * @param buf Byte buffer to receive the data.
  244. * @param siz Maximum length of data to receive.
  245. * @param offset Offset within buffer to place received data.
  246. * @return Actual length of data received.
  247. * @exception java.io.IOException If an I/O error occurs
  248. * @exception SMBException If an SMB level error occurs
  249. */
  250. public abstract int Read(byte[] buf, int siz, int offset)
  251. throws java.io.IOException, SMBException;
  252. /**
  253. * Read a block of data from the file.
  254. *
  255. * @param buf Byte buffer to receive the data.
  256. * @return Actual length of data received.
  257. * @exception java.io.IOException If an I/O error occurs
  258. * @exception SMBException If an SMB level error occurs
  259. */
  260. public final int Read(byte[] buf)
  261. throws java.io.IOException, SMBException {
  262. // Read a full buffer of data
  263. return Read(buf, buf.length, 0);
  264. }
  265. /**
  266. * Write a block of data to the file.
  267. *
  268. * @param buf Byte buffer containing data to be written.
  269. * @param siz Length of data to be written.
  270. * @param offset Offset within buffer to start writing data from.
  271. * @return Actual length of data written.
  272. * @exception java.io.IOException If an I/O error occurs
  273. * @exception SMBException If an SMB level error occurs
  274. */
  275. public abstract int Write(byte[] buf, int siz, int offset)
  276. throws java.io.IOException, SMBException;
  277. /**
  278. * Write a block of data to the file.
  279. *
  280. * @param buf Byte buffer containing data to be written.
  281. * @return Actual length of data written.
  282. * @exception java.io.IOException If an I/O error occurs
  283. * @exception SMBException If an SMB level error occurs
  284. */
  285. public final int Write(byte[] buf)
  286. throws java.io.IOException, SMBException {
  287. // Write the whole buffer
  288. return Write(buf, buf.length, 0);
  289. }
  290. /**
  291. * Write a string to the file.
  292. *
  293. * @param str String to be written to the file
  294. * @return Actual length of data written.
  295. * @exception java.io.IOException If an I/O error occurs
  296. * @exception SMBException If an SMB level error occurs
  297. */
  298. public final int Write(String str)
  299. throws java.io.IOException, SMBException {
  300. // Write the whole buffer
  301. byte[] byts = str.getBytes();
  302. return Write(byts, byts.length, 0);
  303. }
  304. /**
  305. * Seek to the specified point in the file. The seek may be relative to the start of file,
  306. * current file position or end of file.
  307. *
  308. * @param pos Relative offset
  309. * @param typ Seek type. @see org.alfresco.jlan.smb.SeekType
  310. * @return New file offset from start of file
  311. * @exception IOException
  312. * @exception SMBException If an SMB level error occurs
  313. */
  314. public abstract long Seek(long pos, int typ)
  315. throws java.io.IOException, SMBException;
  316. /**
  317. * Lock a range of bytes within the file
  318. *
  319. * @param offset Offset within the file to start lock
  320. * @param len Number of bytes to lock
  321. * @exception IOException
  322. * @exception SMBException If an SMB level error occurs
  323. */
  324. public abstract void Lock(long offset, long len)
  325. throws IOException, SMBException;
  326. /**
  327. * Unlock a range of bytes within the file
  328. *
  329. * @param offset Offset within the file to unlock
  330. * @param len Number of bytes to unlock
  331. * @exception IOException
  332. * @exception SMBException If an SMB level error occurs
  333. */
  334. public abstract void Unlock(long offset, long len)
  335. throws IOException, SMBException;
  336. /**
  337. * Set a file state flag.
  338. *
  339. * @param flag File state flag to set/clear.
  340. * @param sts New file flag state, true or false.
  341. */
  342. protected void setStateFlag(int flag, boolean sts) {
  343. if ( sts == true && (m_flags & flag) == 0)
  344. m_flags += flag;
  345. else if ( sts == false && (m_flags & flag) != 0)
  346. m_flags -= flag;
  347. }
  348. /**
  349. * Set/update the file information
  350. *
  351. * @param fInfo FileInfo
  352. */
  353. protected final void setFileInformation( FileInfo fInfo) {
  354. m_info = fInfo;
  355. }
  356. /**
  357. * Create an input stream using this file
  358. *
  359. * @return SMBInputStream
  360. * @exception SMBException If the file is a directory
  361. */
  362. public final SMBInputStream asInputStream()
  363. throws SMBException {
  364. // Check if the file is a directory
  365. if ( isDirectory())
  366. throw new SMBException(SMBStatus.DOSInvalidFunc, SMBStatus.ErrDos);
  367. // Create the input stream
  368. return new SMBInputStream(this);
  369. }
  370. /**
  371. * Create an output stream using this file
  372. *
  373. * @return SMBOutputStream
  374. * @exception SMBException If the file is a directory
  375. */
  376. public final SMBOutputStream asOutputStream()
  377. throws SMBException {
  378. // Check if the file is a directory
  379. if ( isDirectory())
  380. throw new SMBException(SMBStatus.DOSInvalidFunc, SMBStatus.ErrDos);
  381. // Create the output stream
  382. return new SMBOutputStream(this);
  383. }
  384. /**
  385. * Refresh the file information for an open file
  386. */
  387. public void refreshFileInformation()
  388. throws IOException, SMBException {
  389. // Get the latest file information for the file
  390. if ( m_sess instanceof DiskSession) {
  391. DiskSession diskSess = (DiskSession) m_sess;
  392. FileInfo fInfo = diskSess.getFileInformation( getFileName());
  393. if ( fInfo != null)
  394. setFileInformation( fInfo);
  395. }
  396. }
  397. /**
  398. * Check if the specified state flag is set
  399. *
  400. * @param flg int
  401. * @return boolean
  402. */
  403. protected final boolean hasStateFlag(int flg) {
  404. return (m_flags & flg) != 0 ? true : false;
  405. }
  406. /**
  407. * Return the SMB file as a string
  408. *
  409. * @return SMB file string.
  410. */
  411. public final String toString() {
  412. // Build the file information string
  413. StringBuffer str = new StringBuffer();
  414. // Add the file information string
  415. str.append(m_info.toString());
  416. // Append the SMB file id
  417. str.append(" ,FID=");
  418. str.append(m_FID);
  419. // Return the string
  420. return str.toString();
  421. }
  422. }