RandomAccessFile.java 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738
  1. /*
  2. * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
  3. *
  4. * Portions of this software were developed by the Unidata Program at the
  5. * University Corporation for Atmospheric Research.
  6. *
  7. * Access and use of this software shall impose the following obligations
  8. * and understandings on the user. The user is granted the right, without
  9. * any fee or cost, to use, copy, modify, alter, enhance and distribute
  10. * this software, and any derivative works thereof, and its supporting
  11. * documentation for any purpose whatsoever, provided that this entire
  12. * notice appears in all copies of the software, derivative works and
  13. * supporting documentation. Further, UCAR requests that the user credit
  14. * UCAR/Unidata in any publications that result from the use of this
  15. * software or in any product that includes this software. The names UCAR
  16. * and/or Unidata, however, may not be used in any advertising or publicity
  17. * to endorse or promote any products or commercial entity unless specific
  18. * written permission is obtained from UCAR/Unidata. The user also
  19. * understands that UCAR/Unidata is not obligated to provide the user with
  20. * any support, consulting, training or assistance of any kind with regard
  21. * to the use, operation and performance of this software nor to provide
  22. * the user with any updates, revisions, new versions or "bug fixes."
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
  25. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27. * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
  28. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  29. * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  30. * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  31. * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
  32. */
  33. package info.fetter.logstashforwarder.util;
  34. import java.io.*;
  35. import java.util.*;
  36. import java.util.concurrent.atomic.AtomicInteger;
  37. import java.util.concurrent.atomic.AtomicLong;
  38. import java.nio.channels.WritableByteChannel;
  39. /**
  40. * A buffered drop-in replacement for java.io.RandomAccessFile.
  41. * Instances of this class realise substantial speed increases over
  42. * java.io.RandomAccessFile through the use of buffering. This is a
  43. * subclass of Object, as it was not possible to subclass
  44. * java.io.RandomAccessFile because many of the methods are
  45. * final. However, if it is necessary to use RandomAccessFile and
  46. * java.io.RandomAccessFile interchangeably, both classes implement the
  47. * DataInput and DataOutput interfaces.
  48. * <p/>
  49. * <p> By Russ Rew, based on
  50. * BufferedRandomAccessFile by Alex McManus, based on Sun's source code
  51. * for java.io.RandomAccessFile. For Alex McManus version from which
  52. * this derives, see his <a href="http://www.aber.ac.uk/~agm/Java.html">
  53. * Freeware Java Classes</a>.
  54. * <p/>
  55. *
  56. * @author Alex McManus
  57. * @author Russ Rew
  58. * @author john caron
  59. * @see DataInput
  60. * @see DataOutput
  61. * @see java.io.RandomAccessFile
  62. */
  63. public class RandomAccessFile implements DataInput, DataOutput {
  64. static public final int BIG_ENDIAN = 0;
  65. static public final int LITTLE_ENDIAN = 1;
  66. // debug leaks - keep track of open files
  67. static protected boolean debugLeaks = false;
  68. static protected boolean debugAccess = false;
  69. static protected Set<String> allFiles = new HashSet<String>();
  70. static protected List<String> openFiles = Collections.synchronizedList(new ArrayList<String>());
  71. static private AtomicInteger debug_nseeks = new AtomicInteger();
  72. static private AtomicLong debug_nbytes = new AtomicLong();
  73. /**
  74. * Debugging, do not use.
  75. *
  76. * @return true if debugLeaks is on
  77. */
  78. static public boolean getDebugLeaks() {
  79. return debugLeaks;
  80. }
  81. /**
  82. * Debugging, do not use.
  83. *
  84. * @param b set true to track java.io.RandomAccessFile
  85. */
  86. static public void setDebugLeaks(boolean b) {
  87. debugLeaks = b;
  88. }
  89. /**
  90. * Debugging, do not use.
  91. *
  92. * @return list of open files.
  93. */
  94. static public List<String> getOpenFiles() {
  95. return openFiles;
  96. }
  97. static public List<String> getAllFiles() {
  98. List<String> result = new ArrayList<String>();
  99. if (null == allFiles) return null;
  100. Iterator<String> iter = allFiles.iterator();
  101. while (iter.hasNext()) {
  102. result.add( iter.next());
  103. }
  104. Collections.sort(result);
  105. return result;
  106. }
  107. /**
  108. * Debugging, do not use.
  109. *
  110. * @param b to debug file reading
  111. */
  112. static public void setDebugAccess(boolean b) {
  113. debugAccess = b;
  114. if (b) {
  115. debug_nseeks = new AtomicInteger();
  116. debug_nbytes = new AtomicLong();
  117. }
  118. }
  119. static public int getDebugNseeks() {
  120. return (debug_nseeks == null) ? 0 : debug_nseeks.intValue();
  121. }
  122. static public long getDebugNbytes() {
  123. return (debug_nbytes == null) ? 0 : debug_nbytes.longValue();
  124. }
  125. static protected boolean showOpen = false;
  126. static protected boolean showRead = false;
  127. /**
  128. * The default buffer size, in bytes.
  129. */
  130. protected static final int defaultBufferSize = 8092;
  131. /////////////////////////////////////////////////////////////////////////////////////////////
  132. /**
  133. * File location
  134. */
  135. protected String location;
  136. /**
  137. * The underlying java.io.RandomAccessFile.
  138. */
  139. protected java.io.RandomAccessFile file;
  140. protected java.nio.channels.FileChannel fileChannel;
  141. /**
  142. * The offset in bytes from the file start, of the next read or
  143. * write operation.
  144. */
  145. protected long filePosition;
  146. /**
  147. * The buffer used for reading the data.
  148. */
  149. protected byte buffer[];
  150. /**
  151. * The offset in bytes of the start of the buffer, from the start of the file.
  152. */
  153. protected long bufferStart;
  154. /**
  155. * The offset in bytes of the end of the data in the buffer, from
  156. * the start of the file. This can be calculated from
  157. * <code>bufferStart + dataSize</code>, but it is cached to speed
  158. * up the read( ) method.
  159. */
  160. protected long dataEnd;
  161. /**
  162. * The size of the data stored in the buffer, in bytes. This may be
  163. * less than the size of the buffer.
  164. */
  165. protected int dataSize;
  166. /**
  167. * True if we are at the end of the file.
  168. */
  169. protected boolean endOfFile;
  170. /**
  171. * The access mode of the file.
  172. */
  173. protected boolean readonly;
  174. /**
  175. * The current endian (big or little) mode of the file.
  176. */
  177. protected boolean bigEndian;
  178. /**
  179. * True if the data in the buffer has been modified.
  180. */
  181. boolean bufferModified = false;
  182. /**
  183. * make sure file is this long when closed
  184. */
  185. private long minLength = 0;
  186. /**
  187. * stupid extendMode for truncated, yet valid files - old code allowed NOFILL to do this
  188. */
  189. boolean extendMode = false;
  190. /**
  191. * Constructor, for subclasses
  192. *
  193. * @param bufferSize size of read buffer
  194. */
  195. protected RandomAccessFile(int bufferSize) {
  196. file = null;
  197. readonly = true;
  198. init(bufferSize);
  199. }
  200. /**
  201. * Constructor, default buffer size.
  202. *
  203. * @param location location of the file
  204. * @param mode same as for java.io.RandomAccessFile
  205. * @throws IOException on open error
  206. */
  207. public RandomAccessFile(String location, String mode) throws IOException {
  208. this(location, mode, defaultBufferSize);
  209. this.location = location;
  210. }
  211. /**
  212. * Constructor.
  213. *
  214. * @param location location of the file
  215. * @param mode same as for java.io.RandomAccessFile
  216. * @param bufferSize size of buffer to use.
  217. * @throws IOException on open error
  218. */
  219. public RandomAccessFile(String location, String mode, int bufferSize) throws IOException {
  220. this.location = location;
  221. if (debugLeaks) {
  222. allFiles.add(location);
  223. if ((location.indexOf("01janN") >= 0) || (location.indexOf("02febN") >= 0))
  224. System.out.printf("HEY!%n");
  225. }
  226. this.file = new java.io.RandomAccessFile(location, mode);
  227. this.readonly = mode.equals("r");
  228. init(bufferSize);
  229. if (debugLeaks) {
  230. openFiles.add(location);
  231. if (showOpen) System.out.println(" open " + location);
  232. }
  233. }
  234. /**
  235. * Allow access to the underlying java.io.RandomAccessFile.
  236. * WARNING! BROKEN ENCAPSOLATION, DO NOT USE. May change implementation in the future.
  237. *
  238. * @return the underlying java.io.RandomAccessFile.
  239. */
  240. public java.io.RandomAccessFile getRandomAccessFile() {
  241. return this.file;
  242. }
  243. private void init(int bufferSize) {
  244. // Initialise the buffer
  245. bufferStart = 0;
  246. dataEnd = 0;
  247. dataSize = 0;
  248. filePosition = 0;
  249. buffer = new byte[bufferSize];
  250. endOfFile = false;
  251. }
  252. /**
  253. * Set the buffer size.
  254. * If writing, call flush() first.
  255. *
  256. * @param bufferSize length in bytes
  257. */
  258. public void setBufferSize(int bufferSize) {
  259. init(bufferSize);
  260. }
  261. /**
  262. * Get the buffer size
  263. *
  264. * @return bufferSize length in bytes
  265. */
  266. public int getBufferSize() {
  267. return buffer.length;
  268. }
  269. /**
  270. * Close the file, and release any associated system resources.
  271. *
  272. * @throws IOException if an I/O error occurrs.
  273. */
  274. public void close() throws IOException {
  275. if (debugLeaks) {
  276. openFiles.remove(location);
  277. if (showOpen) System.out.println(" close " + location);
  278. }
  279. if (file == null)
  280. return;
  281. // If we are writing and the buffer has been modified, flush the contents
  282. // of the buffer.
  283. flush();
  284. /*
  285. if (!readonly && bufferModified) {
  286. file.seek(bufferStart);
  287. file.write(buffer, 0, dataSize);
  288. } */
  289. // may need to extend file, in case no fill is being used
  290. // may need to truncate file in case overwriting a longer file
  291. // use only if minLength is set (by N3iosp)
  292. long fileSize = file.length();
  293. if (!readonly && (minLength != 0) && (minLength != fileSize)) {
  294. file.setLength(minLength);
  295. // System.out.println("TRUNCATE!!! minlength="+minLength);
  296. }
  297. // Close the underlying file object.
  298. file.close();
  299. //file = null; // help the gc => commented because of problems with nullpointerexceptions when trying to read after close
  300. }
  301. /**
  302. * Return true if file pointer is at end of file.
  303. *
  304. * @return true if file pointer is at end of file
  305. */
  306. public boolean isAtEndOfFile() {
  307. return endOfFile;
  308. }
  309. /**
  310. * Set the position in the file for the next read or write.
  311. *
  312. * @param pos the offset (in bytes) from the start of the file.
  313. * @throws IOException if an I/O error occurrs.
  314. */
  315. public void seek(long pos) throws IOException {
  316. // If the seek is into the buffer, just update the file pointer.
  317. if ((pos >= bufferStart) && (pos < dataEnd)) {
  318. filePosition = pos;
  319. return;
  320. }
  321. // need new buffer, starting at pos
  322. readBuffer(pos);
  323. }
  324. protected void readBuffer(long pos) throws IOException {
  325. // If the current buffer is modified, write it to disk.
  326. if (bufferModified) {
  327. flush();
  328. }
  329. bufferStart = pos;
  330. filePosition = pos;
  331. dataSize = read_(pos, buffer, 0, buffer.length);
  332. if (dataSize <= 0) {
  333. dataSize = 0;
  334. endOfFile = true;
  335. } else {
  336. endOfFile = false;
  337. }
  338. // Cache the position of the buffer end.
  339. dataEnd = bufferStart + dataSize;
  340. }
  341. /**
  342. * Returns the current position in the file, where the next read or
  343. * write will occur.
  344. *
  345. * @return the offset from the start of the file in bytes.
  346. * @throws IOException if an I/O error occurrs.
  347. */
  348. public long getFilePointer() throws IOException {
  349. return filePosition;
  350. }
  351. /**
  352. * Get the file location, or name.
  353. *
  354. * @return file location
  355. */
  356. public String getLocation() {
  357. return location;
  358. }
  359. /**
  360. * Get the length of the file. The data in the buffer (which may not
  361. * have been written the disk yet) is taken into account.
  362. *
  363. * @return the length of the file in bytes.
  364. * @throws IOException if an I/O error occurrs.
  365. */
  366. public long length() throws IOException {
  367. long fileLength = file.length();
  368. if (fileLength < dataEnd) {
  369. return dataEnd;
  370. } else {
  371. return fileLength;
  372. }
  373. }
  374. /**
  375. * Change the current endian mode. Subsequent reads of short, int, float, double, long, char will
  376. * use this. Does not currently affect writes.
  377. * Default values is BIG_ENDIAN.
  378. *
  379. * @param endian RandomAccessFile.BIG_ENDIAN or RandomAccessFile.LITTLE_ENDIAN
  380. */
  381. public void order(int endian) {
  382. if (endian < 0) return;
  383. this.bigEndian = (endian == BIG_ENDIAN);
  384. }
  385. /**
  386. * Returns the opaque file descriptor object associated with this file.
  387. *
  388. * @return the file descriptor object associated with this file.
  389. * @throws IOException if an I/O error occurs.
  390. */
  391. public FileDescriptor getFD() throws IOException {
  392. return (file == null) ? null : file.getFD();
  393. }
  394. /**
  395. * Copy the contents of the buffer to the disk.
  396. *
  397. * @throws IOException if an I/O error occurs.
  398. */
  399. public void flush() throws IOException {
  400. if (bufferModified) {
  401. file.seek(bufferStart);
  402. file.write(buffer, 0, dataSize);
  403. //System.out.println("--flush at "+bufferStart+" dataSize= "+dataSize+ " filePosition= "+filePosition);
  404. bufferModified = false;
  405. }
  406. /* check min length
  407. if (!readonly && (minLength != 0) && (minLength != file.length())) {
  408. file.setLength(minLength);
  409. } */
  410. }
  411. /**
  412. * Make sure file is at least this long when its closed.
  413. * needed when not using fill mode, and not all data is written.
  414. *
  415. * @param minLength minimum length of the file.
  416. */
  417. public void setMinLength(long minLength) {
  418. this.minLength = minLength;
  419. }
  420. /**
  421. * Set extendMode for truncated, yet valid files - old NetCDF code allowed this
  422. * when NOFILL on, and user doesnt write all variables.
  423. */
  424. public void setExtendMode() {
  425. this.extendMode = true;
  426. }
  427. //////////////////////////////////////////////////////////////////////////////////////////////
  428. // Read primitives.
  429. //
  430. /**
  431. * Read a byte of data from the file, blocking until data is
  432. * available.
  433. *
  434. * @return the next byte of data, or -1 if the end of the file is
  435. * reached.
  436. * @throws IOException if an I/O error occurrs.
  437. */
  438. public int read() throws IOException {
  439. // If the file position is within the data, return the byte...
  440. if (filePosition < dataEnd) {
  441. int pos = (int) (filePosition - bufferStart);
  442. filePosition++;
  443. return (buffer[pos] & 0xff);
  444. // ...or should we indicate EOF...
  445. } else if (endOfFile) {
  446. return -1;
  447. // ...or seek to fill the buffer, and try again.
  448. } else {
  449. seek(filePosition);
  450. return read();
  451. }
  452. }
  453. /**
  454. * Read up to <code>len</code> bytes into an array, at a specified
  455. * offset. This will block until at least one byte has been read.
  456. *
  457. * @param b the byte array to receive the bytes.
  458. * @param off the offset in the array where copying will start.
  459. * @param len the number of bytes to copy.
  460. * @return the actual number of bytes read, or -1 if there is not
  461. * more data due to the end of the file being reached.
  462. * @throws IOException if an I/O error occurrs.
  463. */
  464. protected int readBytes(byte b[], int off, int len) throws IOException {
  465. // Check for end of file.
  466. if (endOfFile) {
  467. return -1;
  468. }
  469. // See how many bytes are available in the buffer - if none,
  470. // seek to the file position to update the buffer and try again.
  471. int bytesAvailable = (int) (dataEnd - filePosition);
  472. if (bytesAvailable < 1) {
  473. seek(filePosition);
  474. return readBytes(b, off, len);
  475. }
  476. // Copy as much as we can.
  477. int copyLength = (bytesAvailable >= len)
  478. ? len
  479. : bytesAvailable;
  480. System.arraycopy(buffer, (int) (filePosition - bufferStart), b, off, copyLength);
  481. filePosition += copyLength;
  482. // If there is more to copy...
  483. if (copyLength < len) {
  484. int extraCopy = len - copyLength;
  485. // If the amount remaining is more than a buffer's length, read it
  486. // directly from the file.
  487. if (extraCopy > buffer.length) {
  488. extraCopy = read_(filePosition, b, off + copyLength, len - copyLength);
  489. // ...or read a new buffer full, and copy as much as possible...
  490. } else {
  491. seek(filePosition);
  492. if (!endOfFile) {
  493. extraCopy = (extraCopy > dataSize)
  494. ? dataSize
  495. : extraCopy;
  496. System.arraycopy(buffer, 0, b, off + copyLength, extraCopy);
  497. } else {
  498. extraCopy = -1;
  499. }
  500. }
  501. // If we did manage to copy any more, update the file position and
  502. // return the amount copied.
  503. if (extraCopy > 0) {
  504. filePosition += extraCopy;
  505. return copyLength + extraCopy;
  506. }
  507. }
  508. // Return the amount copied.
  509. return copyLength;
  510. }
  511. /**
  512. * Read <code>nbytes</code> bytes, at the specified file offset, send to a WritableByteChannel.
  513. * This will block until all bytes are read.
  514. * This uses the underlying file channel directly, bypassing all user buffers.
  515. *
  516. * @param dest write to this WritableByteChannel.
  517. * @param offset the offset in the file where copying will start.
  518. * @param nbytes the number of bytes to read.
  519. * @return the actual number of bytes read and transfered
  520. * @throws IOException if an I/O error occurs.
  521. */
  522. public long readToByteChannel(WritableByteChannel dest, long offset, long nbytes) throws IOException {
  523. if (fileChannel == null)
  524. fileChannel = file.getChannel();
  525. long need = nbytes;
  526. while (need > 0) {
  527. long count = fileChannel.transferTo(offset, need, dest);
  528. //if (count == 0) break; // LOOK not sure what the EOF condition is
  529. need -= count;
  530. offset += count;
  531. }
  532. return nbytes - need;
  533. }
  534. /**
  535. * Read directly from file, without going through the buffer.
  536. * All reading goes through here or readToByteChannel;
  537. *
  538. * @param pos start here in the file
  539. * @param b put data into this buffer
  540. * @param offset buffer offset
  541. * @param len this number of bytes
  542. * @return actual number of bytes read
  543. * @throws IOException on io error
  544. */
  545. protected int read_(long pos, byte[] b, int offset, int len) throws IOException {
  546. file.seek(pos);
  547. int n = file.read(b, offset, len);
  548. if (debugAccess) {
  549. if (showRead) System.out.println(" **read_ " + location + " = " + len + " bytes at " + pos + "; block = " + (pos / buffer.length));
  550. debug_nseeks.incrementAndGet();
  551. debug_nbytes.addAndGet(len);
  552. }
  553. if (extendMode && (n < len)) {
  554. //System.out.println(" read_ = "+len+" at "+pos+"; got = "+n);
  555. n = len;
  556. }
  557. return n;
  558. }
  559. /**
  560. * Read up to <code>len</code> bytes into an array, at a specified
  561. * offset. This will block until at least one byte has been read.
  562. *
  563. * @param b the byte array to receive the bytes.
  564. * @param off the offset in the array where copying will start.
  565. * @param len the number of bytes to copy.
  566. * @return the actual number of bytes read, or -1 if there is not
  567. * more data due to the end of the file being reached.
  568. * @throws IOException if an I/O error occurrs.
  569. */
  570. public int read(byte b[], int off, int len) throws IOException {
  571. return readBytes(b, off, len);
  572. }
  573. /**
  574. * Read up to <code>b.length( )</code> bytes into an array. This
  575. * will block until at least one byte has been read.
  576. *
  577. * @param b the byte array to receive the bytes.
  578. * @return the actual number of bytes read, or -1 if there is not
  579. * more data due to the end of the file being reached.
  580. * @throws IOException if an I/O error occurrs.
  581. */
  582. public int read(byte b[]) throws IOException {
  583. return readBytes(b, 0, b.length);
  584. }
  585. /**
  586. * Read fully count number of bytes
  587. *
  588. * @param count how many bytes tp read
  589. * @return a byte array of length count, fully read in
  590. * @throws IOException if an I/O error occurrs.
  591. */
  592. public byte[] readBytes(int count) throws IOException {
  593. byte[] b = new byte[count];
  594. readFully(b);
  595. return b;
  596. }
  597. /**
  598. * Reads <code>b.length</code> bytes from this file into the byte
  599. * array. This method reads repeatedly from the file until all the
  600. * bytes are read. This method blocks until all the bytes are read,
  601. * the end of the stream is detected, or an exception is thrown.
  602. *
  603. * @param b the buffer into which the data is read.
  604. * @throws EOFException if this file reaches the end before reading
  605. * all the bytes.
  606. * @throws IOException if an I/O error occurs.
  607. */
  608. public final void readFully(byte b[]) throws IOException {
  609. readFully(b, 0, b.length);
  610. }
  611. /**
  612. * Reads exactly <code>len</code> bytes from this file into the byte
  613. * array. This method reads repeatedly from the file until all the
  614. * bytes are read. This method blocks until all the bytes are read,
  615. * the end of the stream is detected, or an exception is thrown.
  616. *
  617. * @param b the buffer into which the data is read.
  618. * @param off the start offset of the data.
  619. * @param len the number of bytes to read.
  620. * @throws EOFException if this file reaches the end before reading
  621. * all the bytes.
  622. * @throws IOException if an I/O error occurs.
  623. */
  624. public final void readFully(byte b[], int off, int len) throws IOException {
  625. int n = 0;
  626. while (n < len) {
  627. int count = this.read(b, off + n, len - n);
  628. if (count < 0) {
  629. throw new EOFException();
  630. }
  631. n += count;
  632. }
  633. }
  634. /**
  635. * Skips exactly <code>n</code> bytes of input.
  636. * This method blocks until all the bytes are skipped, the end of
  637. * the stream is detected, or an exception is thrown.
  638. *
  639. * @param n the number of bytes to be skipped.
  640. * @return the number of bytes skipped, which is always <code>n</code>.
  641. * @throws EOFException if this file reaches the end before skipping
  642. * all the bytes.
  643. * @throws IOException if an I/O error occurs.
  644. */
  645. public int skipBytes(int n) throws IOException {
  646. seek(getFilePointer() + n);
  647. return n;
  648. }
  649. /* public void skipToMultiple( int multipleOfBytes) throws IOException {
  650. long pos = getFilePointer();
  651. int pad = (int) (pos % multipleOfBytes);
  652. if (pad != 0) pad = multipleOfBytes - pad;
  653. if (pad > 0) skipBytes(pad);
  654. } */
  655. /**
  656. * Unread the last byte read.
  657. * This method should not be used more than once
  658. * between reading operations, or strange things might happen.
  659. */
  660. public void unread() {
  661. filePosition--;
  662. }
  663. //
  664. // Write primitives.
  665. //
  666. /**
  667. * Write a byte to the file. If the file has not been opened for
  668. * writing, an IOException will be raised only when an attempt is
  669. * made to write the buffer to the file.
  670. * <p/>
  671. * Caveat: the effects of seek( )ing beyond the end of the file are
  672. * undefined.
  673. *
  674. * @param b write this byte
  675. * @throws IOException if an I/O error occurrs.
  676. */
  677. public void write(int b) throws IOException {
  678. // If the file position is within the block of data...
  679. if (filePosition < dataEnd) {
  680. int pos = (int) (filePosition - bufferStart);
  681. buffer[pos] = (byte) b;
  682. bufferModified = true;
  683. filePosition++;
  684. // ...or (assuming that seek will not allow the file pointer
  685. // to move beyond the end of the file) get the correct block of
  686. // data...
  687. } else {
  688. // If there is room in the buffer, expand it...
  689. if (dataSize != buffer.length) {
  690. int pos = (int) (filePosition - bufferStart);
  691. buffer[pos] = (byte) b;
  692. bufferModified = true;
  693. filePosition++;
  694. dataSize++;
  695. dataEnd++;
  696. // ...or do another seek to get a new buffer, and start again...
  697. } else {
  698. seek(filePosition);
  699. write(b);
  700. }
  701. }
  702. }
  703. /**
  704. * Write <code>len</code> bytes from an array to the file.
  705. *
  706. * @param b the array containing the data.
  707. * @param off the offset in the array to the data.
  708. * @param len the length of the data.
  709. * @throws IOException if an I/O error occurrs.
  710. */
  711. public void writeBytes(byte b[], int off, int len) throws IOException {
  712. // If the amount of data is small (less than a full buffer)...
  713. if (len < buffer.length) {
  714. // If any of the data fits within the buffer...
  715. int spaceInBuffer = 0;
  716. int copyLength = 0;
  717. if (filePosition >= bufferStart) {
  718. spaceInBuffer = (int) ((bufferStart + buffer.length) - filePosition);
  719. }
  720. if (spaceInBuffer > 0) {
  721. // Copy as much as possible to the buffer.
  722. copyLength = (spaceInBuffer > len) ? len : spaceInBuffer;
  723. System.arraycopy(b, off, buffer, (int) (filePosition - bufferStart), copyLength);
  724. bufferModified = true;
  725. long myDataEnd = filePosition + copyLength;
  726. dataEnd = (myDataEnd > dataEnd) ? myDataEnd : dataEnd;
  727. dataSize = (int) (dataEnd - bufferStart);
  728. filePosition += copyLength;
  729. ///System.out.println("--copy to buffer "+copyLength+" "+len);
  730. }
  731. // If there is any data remaining, move to the new position and copy to
  732. // the new buffer.
  733. if (copyLength < len) {
  734. //System.out.println("--need more "+copyLength+" "+len+" space= "+spaceInBuffer);
  735. seek(filePosition); // triggers a flush
  736. System.arraycopy(b, off + copyLength, buffer, (int) (filePosition - bufferStart), len - copyLength);
  737. bufferModified = true;
  738. long myDataEnd = filePosition + (len - copyLength);
  739. dataEnd = (myDataEnd > dataEnd) ? myDataEnd : dataEnd;
  740. dataSize = (int) (dataEnd - bufferStart);
  741. filePosition += (len - copyLength);
  742. }
  743. // ...or write a lot of data...
  744. } else {
  745. // Flush the current buffer, and write this data to the file.
  746. if (bufferModified) {
  747. flush();
  748. }
  749. file.seek(filePosition); // moved per Steve Cerruti; Jan 14, 2005
  750. file.write(b, off, len);
  751. //System.out.println("--write at "+filePosition+" "+len);
  752. filePosition += len;
  753. bufferStart = filePosition; // an empty buffer
  754. dataSize = 0;
  755. dataEnd = bufferStart + dataSize;
  756. }
  757. }
  758. /**
  759. * Writes <code>b.length</code> bytes from the specified byte array
  760. * starting at offset <code>off</code> to this file.
  761. *
  762. * @param b the data.
  763. * @throws IOException if an I/O error occurs.
  764. */
  765. public void write(byte b[]) throws IOException {
  766. writeBytes(b, 0, b.length);
  767. }
  768. /**
  769. * Writes <code>len</code> bytes from the specified byte array
  770. * starting at offset <code>off</code> to this file.
  771. *
  772. * @param b the data.
  773. * @param off the start offset in the data.
  774. * @param len the number of bytes to write.
  775. * @throws IOException if an I/O error occurs.
  776. */
  777. public void write(byte b[], int off, int len) throws IOException {
  778. writeBytes(b, off, len);
  779. }
  780. //
  781. // DataInput methods.
  782. //
  783. /**
  784. * Reads a <code>boolean</code> from this file. This method reads a
  785. * single byte from the file. A value of <code>0</code> represents
  786. * <code>false</code>. Any other value represents <code>true</code>.
  787. * This method blocks until the byte is read, the end of the stream
  788. * is detected, or an exception is thrown.
  789. *
  790. * @return the <code>boolean</code> value read.
  791. * @throws EOFException if this file has reached the end.
  792. * @throws IOException if an I/O error occurs.
  793. */
  794. public final boolean readBoolean() throws IOException {
  795. int ch = this.read();
  796. if (ch < 0) {
  797. throw new EOFException();
  798. }
  799. return (ch != 0);
  800. }
  801. /**
  802. * Reads a signed 8-bit value from this file. This method reads a
  803. * byte from the file. If the byte read is <code>b</code>, where
  804. * <code>0&nbsp;&lt;=&nbsp;b&nbsp;&lt;=&nbsp;255</code>,
  805. * then the result is:
  806. * <ul><code>
  807. * (byte)(b)
  808. * </code></ul>
  809. * <p/>
  810. * This method blocks until the byte is read, the end of the stream
  811. * is detected, or an exception is thrown.
  812. *
  813. * @return the next byte of this file as a signed 8-bit
  814. * <code>byte</code>.
  815. * @throws EOFException if this file has reached the end.
  816. * @throws IOException if an I/O error occurs.
  817. */
  818. public final byte readByte() throws IOException {
  819. int ch = this.read();
  820. if (ch < 0) {
  821. throw new EOFException();
  822. }
  823. return (byte) (ch);
  824. }
  825. /**
  826. * Reads an unsigned 8-bit number from this file. This method reads
  827. * a byte from this file and returns that byte.
  828. * <p/>
  829. * This method blocks until the byte is read, the end of the stream
  830. * is detected, or an exception is thrown.
  831. *
  832. * @return the next byte of this file, interpreted as an unsigned
  833. * 8-bit number.
  834. * @throws EOFException if this file has reached the end.
  835. * @throws IOException if an I/O error occurs.
  836. */
  837. public final int readUnsignedByte() throws IOException {
  838. int ch = this.read();
  839. if (ch < 0) {
  840. throw new EOFException();
  841. }
  842. return ch;
  843. }
  844. /**
  845. * Reads a signed 16-bit number from this file. The method reads 2
  846. * bytes from this file. If the two bytes read, in order, are
  847. * <code>b1</code> and <code>b2</code>, where each of the two values is
  848. * between <code>0</code> and <code>255</code>, inclusive, then the
  849. * result is equal to:
  850. * <ul><code>
  851. * (short)((b1 &lt;&lt; 8) | b2)
  852. * </code></ul>
  853. * <p/>
  854. * This method blocks until the two bytes are read, the end of the
  855. * stream is detected, or an exception is thrown.
  856. *
  857. * @return the next two bytes of this file, interpreted as a signed
  858. * 16-bit number.
  859. * @throws EOFException if this file reaches the end before reading
  860. * two bytes.
  861. * @throws IOException if an I/O error occurs.
  862. */
  863. public final short readShort() throws IOException {
  864. int ch1 = this.read();
  865. int ch2 = this.read();
  866. if ((ch1 | ch2) < 0) {
  867. throw new EOFException();
  868. }
  869. if (bigEndian) {
  870. return (short) ((ch1 << 8) + (ch2));
  871. } else {
  872. return (short) ((ch2 << 8) + (ch1));
  873. }
  874. }
  875. /**
  876. * Read an array of shorts
  877. *
  878. * @param pa read into this array
  879. * @param start starting at pa[start]
  880. * @param n read this many elements
  881. * @throws IOException on read error
  882. */
  883. public final void readShort(short[] pa, int start, int n) throws IOException {
  884. for (int i = 0; i < n; i++) {
  885. pa[start + i] = readShort();
  886. }
  887. }
  888. /**
  889. * Reads an unsigned 16-bit number from this file. This method reads
  890. * two bytes from the file. If the bytes read, in order, are
  891. * <code>b1</code> and <code>b2</code>, where
  892. * <code>0&nbsp;&lt;=&nbsp;b1, b2&nbsp;&lt;=&nbsp;255</code>,
  893. * then the result is equal to:
  894. * <ul><code>
  895. * (b1 &lt;&lt; 8) | b2
  896. * </code></ul>
  897. * <p/>
  898. * This method blocks until the two bytes are read, the end of the
  899. * stream is detected, or an exception is thrown.
  900. *
  901. * @return the next two bytes of this file, interpreted as an unsigned
  902. * 16-bit integer.
  903. * @throws EOFException if this file reaches the end before reading
  904. * two bytes.
  905. * @throws IOException if an I/O error occurs.
  906. */
  907. public final int readUnsignedShort() throws IOException {
  908. int ch1 = this.read();
  909. int ch2 = this.read();
  910. if ((ch1 | ch2) < 0) {
  911. throw new EOFException();
  912. }
  913. if (bigEndian) {
  914. return ((ch1 << 8) + (ch2));
  915. } else {
  916. return ((ch2 << 8) + (ch1));
  917. }
  918. }
  919. /*
  920. * Reads a signed 24-bit integer from this file. This method reads 3
  921. * bytes from the file. If the bytes read, in order, are <code>b1</code>,
  922. * <code>b2</code>, and <code>b3</code>, where
  923. * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3&nbsp;&lt;=&nbsp;255</code>,
  924. * then the result is equal to:
  925. * <ul><code>
  926. * (b1 &lt;&lt; 16) | (b2 &lt;&lt; 8) + (b3 &lt;&lt; 0)
  927. * </code></ul>
  928. * <p/>
  929. * This method blocks until the three bytes are read, the end of the
  930. * stream is detected, or an exception is thrown.
  931. */
  932. /**
  933. * Reads a Unicode character from this file. This method reads two
  934. * bytes from the file. If the bytes read, in order, are
  935. * <code>b1</code> and <code>b2</code>, where
  936. * <code>0&nbsp;&lt;=&nbsp;b1,&nbsp;b2&nbsp;&lt;=&nbsp;255</code>,
  937. * then the result is equal to:
  938. * <ul><code>
  939. * (char)((b1 &lt;&lt; 8) | b2)
  940. * </code></ul>
  941. * <p/>
  942. * This method blocks until the two bytes are read, the end of the
  943. * stream is detected, or an exception is thrown.
  944. *
  945. * @return the next two bytes of this file as a Unicode character.
  946. * @throws EOFException if this file reaches the end before reading
  947. * two bytes.
  948. * @throws IOException if an I/O error occurs.
  949. */
  950. public final char readChar() throws IOException {
  951. int ch1 = this.read();
  952. int ch2 = this.read();
  953. if ((ch1 | ch2) < 0) {
  954. throw new EOFException();
  955. }
  956. if (bigEndian) {
  957. return (char) ((ch1 << 8) + (ch2));
  958. } else {
  959. return (char) ((ch2 << 8) + (ch1));
  960. }
  961. }
  962. /**
  963. * Reads a signed 32-bit integer from this file. This method reads 4
  964. * bytes from the file. If the bytes read, in order, are <code>b1</code>,
  965. * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
  966. * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
  967. * then the result is equal to:
  968. * <ul><code>
  969. * (b1 &lt;&lt; 24) | (b2 &lt;&lt; 16) + (b3 &lt;&lt; 8) + b4
  970. * </code></ul>
  971. * <p/>
  972. * This method blocks until the four bytes are read, the end of the
  973. * stream is detected, or an exception is thrown.
  974. *
  975. * @return the next four bytes of this file, interpreted as an
  976. * <code>int</code>.
  977. * @throws EOFException if this file reaches the end before reading
  978. * four bytes.
  979. * @throws IOException if an I/O error occurs.
  980. */
  981. public final int readInt() throws IOException {
  982. int ch1 = this.read();
  983. int ch2 = this.read();
  984. int ch3 = this.read();
  985. int ch4 = this.read();
  986. if ((ch1 | ch2 | ch3 | ch4) < 0) {
  987. throw new EOFException();
  988. }
  989. if (bigEndian) {
  990. return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4));
  991. } else {
  992. return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1));
  993. }
  994. }
  995. /**
  996. * Read an integer at the given position, bypassing all buffering.
  997. *
  998. * @param pos read a byte at this position
  999. * @return The int that was read
  1000. * @throws IOException if an I/O error occurs.
  1001. */
  1002. public final int readIntUnbuffered(long pos) throws IOException {
  1003. byte[] bb = new byte[4];
  1004. read_(pos, bb, 0, 4);
  1005. int ch1 = bb[0] & 0xff;
  1006. int ch2 = bb[1] & 0xff;
  1007. int ch3 = bb[2] & 0xff;
  1008. int ch4 = bb[3] & 0xff;
  1009. if ((ch1 | ch2 | ch3 | ch4) < 0) {
  1010. throw new EOFException();
  1011. }
  1012. if (bigEndian) {
  1013. return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4));
  1014. } else {
  1015. return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1));
  1016. }
  1017. }
  1018. /**
  1019. * Read an array of ints
  1020. *
  1021. * @param pa read into this array
  1022. * @param start starting at pa[start]
  1023. * @param n read this many elements
  1024. * @throws IOException on read error
  1025. */
  1026. public final void readInt(int[] pa, int start, int n) throws IOException {
  1027. for (int i = 0; i < n; i++) {
  1028. pa[start + i] = readInt();
  1029. }
  1030. }
  1031. /**
  1032. * Reads a signed 64-bit integer from this file. This method reads eight
  1033. * bytes from the file. If the bytes read, in order, are
  1034. * <code>b1</code>, <code>b2</code>, <code>b3</code>,
  1035. * <code>b4</code>, <code>b5</code>, <code>b6</code>,
  1036. * <code>b7</code>, and <code>b8,</code> where:
  1037. * <ul><code>
  1038. * 0 &lt;= b1, b2, b3, b4, b5, b6, b7, b8 &lt;=255,
  1039. * </code></ul>
  1040. * <p/>
  1041. * then the result is equal to:
  1042. * <p><blockquote><pre>
  1043. * ((long)b1 &lt;&lt; 56) + ((long)b2 &lt;&lt; 48)
  1044. * + ((long)b3 &lt;&lt; 40) + ((long)b4 &lt;&lt; 32)
  1045. * + ((long)b5 &lt;&lt; 24) + ((long)b6 &lt;&lt; 16)
  1046. * + ((long)b7 &lt;&lt; 8) + b8
  1047. * </pre></blockquote>
  1048. * <p/>
  1049. * This method blocks until the eight bytes are read, the end of the
  1050. * stream is detected, or an exception is thrown.
  1051. *
  1052. * @return the next eight bytes of this file, interpreted as a
  1053. * <code>long</code>.
  1054. * @throws EOFException if this file reaches the end before reading
  1055. * eight bytes.
  1056. * @throws IOException if an I/O error occurs.
  1057. */
  1058. public final long readLong() throws IOException {
  1059. if (bigEndian) {
  1060. return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL); // tested ok
  1061. } else {
  1062. return ((readInt() & 0xFFFFFFFFL) + ((long) readInt() << 32)); // not tested yet ??
  1063. }
  1064. /* int ch1 = this.read();
  1065. int ch2 = this.read();
  1066. int ch3 = this.read();
  1067. int ch4 = this.read();
  1068. int ch5 = this.read();
  1069. int ch6 = this.read();
  1070. int ch7 = this.read();
  1071. int ch8 = this.read();
  1072. if ((ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8) < 0)
  1073. throw new EOFException();
  1074. if (bigEndian)
  1075. return ((long)(ch1 << 56)) + (ch2 << 48) + (ch3 << 40) + (ch4 << 32) + (ch5 << 24) + (ch6 << 16) + (ch7 << 8) + (ch8 << 0));
  1076. else
  1077. return ((long)(ch8 << 56) + (ch7 << 48) + (ch6 << 40) + (ch5 << 32) + (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
  1078. */
  1079. }
  1080. /**
  1081. * Read an array of longs
  1082. *
  1083. * @param pa read into this array
  1084. * @param start starting at pa[start]
  1085. * @param n read this many elements
  1086. * @throws IOException on read error
  1087. */
  1088. public final void readLong(long[] pa, int start, int n) throws IOException {
  1089. for (int i = 0; i < n; i++) {
  1090. pa[start + i] = readLong();
  1091. }
  1092. }
  1093. /**
  1094. * Reads a <code>float</code> from this file. This method reads an
  1095. * <code>int</code> value as if by the <code>readInt</code> method
  1096. * and then converts that <code>int</code> to a <code>float</code>
  1097. * using the <code>intBitsToFloat</code> method in class
  1098. * <code>Float</code>.
  1099. * <p/>
  1100. * This method blocks until the four bytes are read, the end of the
  1101. * stream is detected, or an exception is thrown.
  1102. *
  1103. * @return the next four bytes of this file, interpreted as a
  1104. * <code>float</code>.
  1105. * @throws EOFException if this file reaches the end before reading
  1106. * four bytes.
  1107. * @throws IOException if an I/O error occurs.
  1108. * @see java.io.RandomAccessFile#readInt()
  1109. * @see java.lang.Float#intBitsToFloat(int)
  1110. */
  1111. public final float readFloat() throws IOException {
  1112. return Float.intBitsToFloat(readInt());
  1113. }
  1114. /**
  1115. * Read an array of floats
  1116. *
  1117. * @param pa read into this array
  1118. * @param start starting at pa[start]
  1119. * @param n read this many elements
  1120. * @throws IOException on read error
  1121. */
  1122. public final void readFloat(float[] pa, int start, int n) throws IOException {
  1123. for (int i = 0; i < n; i++) {
  1124. pa[start + i] = Float.intBitsToFloat(readInt());
  1125. }
  1126. }
  1127. /**
  1128. * Reads a <code>double</code> from this file. This method reads a
  1129. * <code>long</code> value as if by the <code>readLong</code> method
  1130. * and then converts that <code>long</code> to a <code>double</code>
  1131. * using the <code>longBitsToDouble</code> method in
  1132. * class <code>Double</code>.
  1133. * <p/>
  1134. * This method blocks until the eight bytes are read, the end of the
  1135. * stream is detected, or an exception is thrown.
  1136. *
  1137. * @return the next eight bytes of this file, interpreted as a
  1138. * <code>double</code>.
  1139. * @throws EOFException if this file reaches the end before reading
  1140. * eight bytes.
  1141. * @throws IOException if an I/O error occurs.
  1142. * @see java.io.RandomAccessFile#readLong()
  1143. * @see java.lang.Double#longBitsToDouble(long)
  1144. */
  1145. public final double readDouble() throws IOException {
  1146. return Double.longBitsToDouble(readLong());
  1147. }
  1148. /**
  1149. * Read an array of doubles
  1150. *
  1151. * @param pa read into this array
  1152. * @param start starting at pa[start]
  1153. * @param n read this many elements
  1154. * @throws IOException on read error
  1155. */
  1156. public final void readDouble(double[] pa, int start, int n) throws IOException {
  1157. for (int i = 0; i < n; i++) {
  1158. pa[start + i] = Double.longBitsToDouble(readLong());
  1159. }
  1160. }
  1161. /**
  1162. * Reads the next line of text from this file. This method
  1163. * successively reads bytes from the file until it reaches the end of
  1164. * a line of text.
  1165. * <p/>
  1166. * <p/>
  1167. * A line of text is terminated by a carriage-return character
  1168. * (<code>'&#92;r'</code>), a newline character (<code>'&#92;n'</code>), a
  1169. * carriage-return character immediately followed by a newline
  1170. * character, or the end of the input stream. The line-terminating
  1171. * character(s), if any, are included as part of the string returned.
  1172. * <p/>
  1173. * <p/>
  1174. * This method blocks until a newline character is read, a carriage
  1175. * return and the byte following it are read (to see if it is a
  1176. * newline), the end of the stream is detected, or an exception is thrown.
  1177. *
  1178. * @return the next line of text from this file.
  1179. * @throws IOException if an I/O error occurs.
  1180. */
  1181. public final String readLine() throws IOException {
  1182. StringBuilder input = new StringBuilder();
  1183. int c;
  1184. while (((c = read()) != -1) && (c != '\n')) {
  1185. input.append((char) c);
  1186. }
  1187. if ((c == -1) && (input.length() == 0)) {
  1188. return null;
  1189. }
  1190. return input.toString();
  1191. }
  1192. /**
  1193. * Reads in a string from this file. The string has been encoded
  1194. * using a modified UTF-8 format.
  1195. * <p/>
  1196. * The first two bytes are read as if by
  1197. * <code>readUnsignedShort</code>. This value gives the number of
  1198. * following bytes that are in the encoded string, not
  1199. * the length of the resulting string. The following bytes are then
  1200. * interpreted as bytes encoding characters in the UTF-8 format
  1201. * and are converted into characters.
  1202. * <p/>
  1203. * This method blocks until all the bytes are read, the end of the
  1204. * stream is detected, or an exception is thrown.
  1205. *
  1206. * @return a Unicode string.
  1207. * @throws EOFException if this file reaches the end before
  1208. * reading all the bytes.
  1209. * @throws IOException if an I/O error occurs.
  1210. * @throws UTFDataFormatException if the bytes do not represent
  1211. * valid UTF-8 encoding of a Unicode string.
  1212. * @see java.io.RandomAccessFile#readUnsignedShort()
  1213. */
  1214. public final String readUTF() throws IOException {
  1215. return DataInputStream.readUTF(this);
  1216. }
  1217. /**
  1218. * Read a String of knoen length.
  1219. *
  1220. * @param nbytes number of bytes to read
  1221. * @return String wrapping the bytes.
  1222. * @throws IOException if an I/O error occurs.
  1223. */
  1224. public String readString(int nbytes) throws IOException {
  1225. byte[] data = new byte[nbytes];
  1226. readFully(data);
  1227. return new String(data);
  1228. }
  1229. //
  1230. // DataOutput methods.
  1231. //
  1232. /**
  1233. * Writes a <code>boolean</code> to the file as a 1-byte value. The
  1234. * value <code>true</code> is written out as the value
  1235. * <code>(byte)1</code>; the value <code>false</code> is written out
  1236. * as the value <code>(byte)0</code>.
  1237. *
  1238. * @param v a <code>boolean</code> value to be written.
  1239. * @throws IOException if an I/O error occurs.
  1240. */
  1241. public final void writeBoolean(boolean v) throws IOException {
  1242. write(v ? 1 : 0);
  1243. }
  1244. /**
  1245. * Write an array of booleans
  1246. *
  1247. * @param pa write from this array
  1248. * @param start starting with this element in the array
  1249. * @param n write this number of elements
  1250. * @throws IOException on read error
  1251. */
  1252. public final void writeBoolean(boolean[] pa, int start, int n) throws IOException {
  1253. for (int i = 0; i < n; i++) {
  1254. writeBoolean(pa[start + i]);
  1255. }
  1256. }
  1257. /**
  1258. * Writes a <code>byte</code> to the file as a 1-byte value.
  1259. *
  1260. * @param v a <code>byte</code> value to be written.
  1261. * @throws IOException if an I/O error occurs.
  1262. */
  1263. public final void writeByte(int v) throws IOException {
  1264. write(v);
  1265. }
  1266. /**
  1267. * Writes a <code>short</code> to the file as two bytes, high byte first.
  1268. *
  1269. * @param v a <code>short</code> to be written.
  1270. * @throws IOException if an I/O error occurs.
  1271. */
  1272. public final void writeShort(int v) throws IOException {
  1273. write((v >>> 8) & 0xFF);
  1274. write((v) & 0xFF);
  1275. }
  1276. /**
  1277. * Write an array of shorts
  1278. *
  1279. * @param pa write from this array
  1280. * @param start starting with this element in the array
  1281. * @param n this number of elements
  1282. * @throws IOException on read error
  1283. */
  1284. public final void writeShort(short[] pa, int start, int n) throws IOException {
  1285. for (int i = 0; i < n; i++) {
  1286. writeShort(pa[start + i]);
  1287. }
  1288. }
  1289. /**
  1290. * Writes a <code>char</code> to the file as a 2-byte value, high
  1291. * byte first.
  1292. *
  1293. * @param v a <code>char</code> value to be written.
  1294. * @throws IOException if an I/O error occurs.
  1295. */
  1296. public final void writeChar(int v) throws IOException {
  1297. write((v >>> 8) & 0xFF);
  1298. write((v) & 0xFF);
  1299. }
  1300. /**
  1301. * Write an array of chars
  1302. *
  1303. * @param pa write from this array
  1304. * @param start starting with this element in the array
  1305. * @param n this number of elements
  1306. * @throws IOException on read error
  1307. */
  1308. public final void writeChar(char[] pa, int start, int n) throws IOException {
  1309. for (int i = 0; i < n; i++) {
  1310. writeChar(pa[start + i]);
  1311. }
  1312. }
  1313. /**
  1314. * Writes an <code>int</code> to the file as four bytes, high byte first.
  1315. *
  1316. * @param v an <code>int</code> to be written.
  1317. * @throws IOException if an I/O error occurs.
  1318. */
  1319. public final void writeInt(int v) throws IOException {
  1320. write((v >>> 24) & 0xFF);
  1321. write((v >>> 16) & 0xFF);
  1322. write((v >>> 8) & 0xFF);
  1323. write((v) & 0xFF);
  1324. }
  1325. /**
  1326. * Write an array of ints
  1327. *
  1328. * @param pa write from this array
  1329. * @param start starting with this element in the array
  1330. * @param n write this number of elements
  1331. * @throws IOException on read error
  1332. */
  1333. public final void writeInt(int[] pa, int start, int n) throws IOException {
  1334. for (int i = 0; i < n; i++) {
  1335. writeInt(pa[start + i]);
  1336. }
  1337. }
  1338. /**
  1339. * Writes a <code>long</code> to the file as eight bytes, high byte first.
  1340. *
  1341. * @param v a <code>long</code> to be written.
  1342. * @throws IOException if an I/O error occurs.
  1343. */
  1344. public final void writeLong(long v) throws IOException {
  1345. write((int) (v >>> 56) & 0xFF);
  1346. write((int) (v >>> 48) & 0xFF);
  1347. write((int) (v >>> 40) & 0xFF);
  1348. write((int) (v >>> 32) & 0xFF);
  1349. write((int) (v >>> 24) & 0xFF);
  1350. write((int) (v >>> 16) & 0xFF);
  1351. write((int) (v >>> 8) & 0xFF);
  1352. write((int) (v) & 0xFF);
  1353. }
  1354. /**
  1355. * Write an array of longs
  1356. *
  1357. * @param pa write from this array
  1358. * @param start starting with this element in the array
  1359. * @param n write this number of elements
  1360. * @throws IOException on read error
  1361. */
  1362. public final void writeLong(long[] pa, int start, int n) throws IOException {
  1363. for (int i = 0; i < n; i++) {
  1364. writeLong(pa[start + i]);
  1365. }
  1366. }
  1367. /**
  1368. * Converts the float argument to an <code>int</code> using the
  1369. * <code>floatToIntBits</code> method in class <code>Float</code>,
  1370. * and then writes that <code>int</code> value to the file as a
  1371. * 4-byte quantity, high byte first.
  1372. *
  1373. * @param v a <code>float</code> value to be written.
  1374. * @throws IOException if an I/O error occurs.
  1375. * @see java.lang.Float#floatToIntBits(float)
  1376. */
  1377. public final void writeFloat(float v) throws IOException {
  1378. writeInt(Float.floatToIntBits(v));
  1379. }
  1380. /**
  1381. * Write an array of floats
  1382. *
  1383. * @param pa write from this array
  1384. * @param start starting with this element in the array
  1385. * @param n write this number of elements
  1386. * @throws IOException on read error
  1387. */
  1388. public final void writeFloat(float[] pa, int start, int n) throws IOException {
  1389. for (int i = 0; i < n; i++) {
  1390. writeFloat(pa[start + i]);
  1391. }
  1392. }
  1393. /**
  1394. * Converts the double argument to a <code>long</code> using the
  1395. * <code>doubleToLongBits</code> method in class <code>Double</code>,
  1396. * and then writes that <code>long</code> value to the file as an
  1397. * 8-byte quantity, high byte first.
  1398. *
  1399. * @param v a <code>double</code> value to be written.
  1400. * @throws IOException if an I/O error occurs.
  1401. * @see java.lang.Double#doubleToLongBits(double)
  1402. */
  1403. public final void writeDouble(double v) throws IOException {
  1404. writeLong(Double.doubleToLongBits(v));
  1405. }
  1406. /**
  1407. * Write an array of doubles
  1408. *
  1409. * @param pa write from this array
  1410. * @param start starting with this element in the array
  1411. * @param n write this number of elements
  1412. * @throws IOException on read error
  1413. */
  1414. public final void writeDouble(double[] pa, int start, int n) throws IOException {
  1415. for (int i = 0; i < n; i++) {
  1416. writeDouble(pa[start + i]);
  1417. }
  1418. }
  1419. /**
  1420. * Writes the string to the file as a sequence of bytes. Each
  1421. * character in the string is written out, in sequence, by discarding
  1422. * its high eight bits.
  1423. *
  1424. * @param s a string of bytes to be written.
  1425. * @throws IOException if an I/O error occurs.
  1426. */
  1427. public final void writeBytes(String s) throws IOException {
  1428. int len = s.length();
  1429. for (int i = 0; i < len; i++) {
  1430. write((byte) s.charAt(i));
  1431. }
  1432. }
  1433. /**
  1434. * Writes the character array to the file as a sequence of bytes. Each
  1435. * character in the string is written out, in sequence, by discarding
  1436. * its high eight bits.
  1437. *
  1438. * @param b a character array of bytes to be written.
  1439. * @param off the index of the first character to write.
  1440. * @param len the number of characters to write.
  1441. * @throws IOException if an I/O error occurs.
  1442. */
  1443. public final void writeBytes(char b[], int off, int len) throws IOException {
  1444. for (int i = off; i < len; i++) {
  1445. write((byte) b[i]);
  1446. }
  1447. }
  1448. /**
  1449. * Writes a string to the file as a sequence of characters. Each
  1450. * character is written to the data output stream as if by the
  1451. * <code>writeChar</code> method.
  1452. *
  1453. * @param s a <code>String</code> value to be written.
  1454. * @throws IOException if an I/O error occurs.
  1455. * @see java.io.RandomAccessFile#writeChar(int)
  1456. */
  1457. public final void writeChars(String s) throws IOException {
  1458. int len = s.length();
  1459. for (int i = 0; i < len; i++) {
  1460. int v = s.charAt(i);
  1461. write((v >>> 8) & 0xFF);
  1462. write((v) & 0xFF);
  1463. }
  1464. }
  1465. /**
  1466. * Writes a string to the file using UTF-8 encoding in a
  1467. * machine-independent manner.
  1468. * <p/>
  1469. * First, two bytes are written to the file as if by the
  1470. * <code>writeShort</code> method giving the number of bytes to
  1471. * follow. This value is the number of bytes actually written out,
  1472. * not the length of the string. Following the length, each character
  1473. * of the string is output, in sequence, using the UTF-8 encoding
  1474. * for each character.
  1475. *
  1476. * @param str a string to be written.
  1477. * @throws IOException if an I/O error occurs.
  1478. */
  1479. public final void writeUTF(String str) throws IOException {
  1480. int strlen = str.length();
  1481. int utflen = 0;
  1482. for (int i = 0; i < strlen; i++) {
  1483. int c = str.charAt(i);
  1484. if ((c >= 0x0001) && (c <= 0x007F)) {
  1485. utflen++;
  1486. } else if (c > 0x07FF) {
  1487. utflen += 3;
  1488. } else {
  1489. utflen += 2;
  1490. }
  1491. }
  1492. if (utflen > 65535) {
  1493. throw new UTFDataFormatException();
  1494. }
  1495. write((utflen >>> 8) & 0xFF);
  1496. write((utflen) & 0xFF);
  1497. for (int i = 0; i < strlen; i++) {
  1498. int c = str.charAt(i);
  1499. if ((c >= 0x0001) && (c <= 0x007F)) {
  1500. write(c);
  1501. } else if (c > 0x07FF) {
  1502. write(0xE0 | ((c >> 12) & 0x0F));
  1503. write(0x80 | ((c >> 6) & 0x3F));
  1504. write(0x80 | ((c) & 0x3F));
  1505. } else {
  1506. write(0xC0 | ((c >> 6) & 0x1F));
  1507. write(0x80 | ((c) & 0x3F));
  1508. }
  1509. }
  1510. }
  1511. /**
  1512. * Create a string representation of this object.
  1513. *
  1514. * @return a string representation of the state of the object.
  1515. */
  1516. public String toString() {
  1517. return "fp=" + filePosition + ", bs=" + bufferStart + ", de="
  1518. + dataEnd + ", ds=" + dataSize + ", bl=" + buffer.length
  1519. + ", readonly=" + readonly + ", bm=" + bufferModified;
  1520. }
  1521. /////////////////////////////////////////////////
  1522. /**
  1523. * Search forward from the current pos, looking for a match.
  1524. *
  1525. * @param match the match to look for.
  1526. * @param maxBytes maximum number of bytes to search. use -1 for all
  1527. * @return true if found, file position will be at the start of the match.
  1528. * @throws IOException on read error
  1529. */
  1530. public boolean searchForward(KMPMatch match, int maxBytes) throws IOException {
  1531. long start = getFilePointer();
  1532. long last = (maxBytes < 0) ? length() : Math.min(length(), start + maxBytes);
  1533. long needToScan = last - start;
  1534. // check what ever is now in the buffer
  1535. int bytesAvailable = (int) (dataEnd - filePosition);
  1536. if (bytesAvailable < 1) {
  1537. seek(filePosition); // read a new buffer
  1538. bytesAvailable = (int) (dataEnd - filePosition);
  1539. }
  1540. int bufStart = (int) (filePosition - bufferStart);
  1541. int scanBytes = (int) Math.min(bytesAvailable, needToScan);
  1542. int pos = match.indexOf(buffer, bufStart, scanBytes);
  1543. if (pos >= 0) {
  1544. seek(bufferStart + pos);
  1545. return true;
  1546. }
  1547. int matchLen = match.getMatchLength();
  1548. needToScan -= scanBytes - matchLen;
  1549. while (needToScan > matchLen) {
  1550. readBuffer(dataEnd - matchLen); // force new buffer
  1551. scanBytes = (int) Math.min(buffer.length, needToScan);
  1552. pos = match.indexOf(buffer, 0, scanBytes);
  1553. if (pos > 0) {
  1554. seek(bufferStart + pos);
  1555. return true;
  1556. }
  1557. needToScan -= scanBytes - matchLen;
  1558. }
  1559. // failure
  1560. seek(last);
  1561. return false;
  1562. }
  1563. }