/** * Write (either create or replace) a binary file on the local machine with one read from the * server. * * @param path the absolute path of the file, (including the file name). * @param mode the mode of the file * @param dis the stream to read the file from, as bytes * @param length the number of bytes to read */ @Override public void writeBinaryFile(String path, String mode, LoggedDataInputStream dis, int length) throws IOException { if (DEBUG) { System.err.println("[writeBinaryFile] writing: " + path); // NOI18N System.err.println("[writeBinaryFile] length: " + length); // NOI18N System.err.println("Reader object is: " + dis.hashCode()); // NOI18N } File file = new File(path); boolean readOnly = resetReadOnly(file); createNewFile(file); // FUTURE: optimisation possible - no need to use a temp file if there // is no post processing required (e.g. unzipping). So perhaps enhance // the interface to allow this stage to be optional File cvsDir = new File(file.getParentFile(), "CVS"); cvsDir.mkdir(); File tempFile = File.createTempFile("cvsPostConversion", "tmp", cvsDir); // NOI18N try { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempFile)); byte[] chunk = new byte[CHUNK_SIZE]; try { while (length > 0) { int bytesToRead = length >= CHUNK_SIZE ? CHUNK_SIZE : (int) length; int count = dis.read(chunk, 0, bytesToRead); if (count == -1) { throw new IOException( "Unexpected end of stream: " + path + "\nMissing " + length + " bytes. Probably network communication failure.\nPlease try again."); // NOI18N } if (count < 0) { break; } length -= count; if (DEBUG) { System.err.println("Still got: " + length + " to read"); // NOI18N } bos.write(chunk, 0, count); } } finally { bos.close(); } // Here we read the temp file in, taking the opportunity to process // the file, e.g. unzip the data BufferedInputStream tempIS = new BufferedInputStream(getProcessedInputStream(tempFile)); bos = new BufferedOutputStream(createOutputStream(file)); try { for (int count = tempIS.read(chunk, 0, CHUNK_SIZE); count > 0; count = tempIS.read(chunk, 0, CHUNK_SIZE)) { bos.write(chunk, 0, count); } } finally { bos.close(); tempIS.close(); } // now we need to modifiy the timestamp on the file, if specified if (modifiedDate != null) { file.setLastModified(modifiedDate.getTime()); modifiedDate = null; } } finally { tempFile.delete(); } if (readOnly) { FileUtils.setFileReadOnly(file, true); } }
/** * Common code for writeTextFile() and writeRcsDiffFile() methods. Differs only in the passed file * processor. */ private void writeAndPostProcessTextFile( String path, String mode, LoggedDataInputStream dis, int length, WriteTextFilePreprocessor processor) throws IOException { if (DEBUG) { System.err.println("[writeTextFile] writing: " + path); // NOI18N System.err.println("[writeTextFile] length: " + length); // NOI18N System.err.println("Reader object is: " + dis.hashCode()); // NOI18N } File file = new File(path); boolean readOnly = resetReadOnly(file); createNewFile(file); // For CRLF conversion, we have to read the file // into a temp file, then do the conversion. This is because we cannot // perform a sequence of readLines() until we've read the file from // the server - the file transmission is not followed by a newline. // Bah. File tempFile = File.createTempFile("cvsCRLF", "tmp"); // NOI18N try { OutputStream os = null; try { os = new BufferedOutputStream(new FileOutputStream(tempFile)); byte[] chunk = new byte[CHUNK_SIZE]; while (length > 0) { int count = length >= CHUNK_SIZE ? CHUNK_SIZE : length; count = dis.read(chunk, 0, count); if (count == -1) { throw new IOException( "Unexpected end of stream: " + path + "\nMissing " + length + " bytes. Probably network communication failure.\nPlease try again."); // NOI18N } length -= count; if (DEBUG) { System.err.println("Still got: " + length + " to read"); // NOI18N } os.write(chunk, 0, count); } } finally { if (os != null) { try { os.close(); } catch (IOException ex) { // ignore } } } // Here we read the temp file in again, doing any processing required // (for example, unzipping). We must not convert bytes to characters // because it would break characters that are not in the current encoding InputStream tempInput = getProcessedInputStream(tempFile); try { // BUGLOG - assert the processor is not null.. processor.copyTextFileToLocation(tempInput, file, new StreamProvider(file)); } finally { tempInput.close(); } if (modifiedDate != null) { file.setLastModified(modifiedDate.getTime()); modifiedDate = null; } } finally { tempFile.delete(); } if (readOnly) { FileUtils.setFileReadOnly(file, true); } }