📄 textfile.java
字号:
/*====================================================================*\TextFile.javaText file class.------------------------------------------------------------------------This file is part of FuncPlotter, a combined Java application and appletfor plotting explicit functions in one variable.Copyright 2005-2007 Andy Morgan-Richards.FuncPlotter is free software: you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation, either version 3 of the License, or (at youroption) any later version.This program is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith this program. If not, see <http://www.gnu.org/licenses/>.\*====================================================================*/// PACKAGEpackage util;//----------------------------------------------------------------------// IMPORTSimport exception.AppException;import exception.FileException;import exception.TempFileException;import exception.TerminatedException;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import java.nio.channels.FileChannel;import java.nio.charset.Charset;import java.util.ArrayList;import java.util.List;//----------------------------------------------------------------------// TEXT FILE CLASSpublic class TextFile{////////////////////////////////////////////////////////////////////////// Constants//////////////////////////////////////////////////////////////////////// public interface LineSeparator { int LF = 0; int CR = 1; int CR_LF = 2; } public static final int NUM_LINE_SEPARATOR_TYPES = 3; private static final int BLOCK_LENGTH = 8192; private static final String TEMP_FILE_PREFIX = "_$_";////////////////////////////////////////////////////////////////////////// Enumeration types//////////////////////////////////////////////////////////////////////// // ERROR IDENTIFIERS private enum ErrorId implements AppException.Id { //////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////// FAILED_TO_OPEN_FILE ( "Failed to open the file." ), FAILED_TO_CLOSE_FILE ( "Failed to close the file." ), FAILED_TO_LOCK_FILE ( "Failed to lock the file." ), ERROR_READING_FILE ( "An error occurred when reading the file." ), ERROR_WRITING_FILE ( "An error occurred when writing the file." ), FAILED_TO_CREATE_TEMPORARY_FILE ( "Failed to create a temporary file." ), FAILED_TO_DELETE_FILE ( "Failed to delete the existing file." ), FAILED_TO_RENAME_FILE ( "Failed to rename the temporary file to the specified filename." ), FILE_ACCESS_NOT_PERMITTED ( "Access to the file was not permitted." ), NOT_ENOUGH_MEMORY_TO_READ_FILE ( "There was not enough memory to read the file." ), ENCODING_NOT_SUPPORTED ( "This implementation of Java does not support the %1 encoding." ), FILE_IS_TOO_LONG ( "The file is too long to be read by this program." ); //////////////////////////////////////////////////////////////////// // Constructors //////////////////////////////////////////////////////////////////// private ErrorId( String message ) { this.message = message; } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance methods : AppException.Id interface //////////////////////////////////////////////////////////////////// public String getMessage( ) { return message; } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance variables //////////////////////////////////////////////////////////////////// private String message; } //==================================================================////////////////////////////////////////////////////////////////////////// Member interfaces//////////////////////////////////////////////////////////////////////// // PROGRESS LISTENER INTERFACE public interface ProgressListener { //////////////////////////////////////////////////////////////////// // Methods //////////////////////////////////////////////////////////////////// void progress( double fractionDone ); //-------------------------------------------------------------- boolean isOperationTerminated( ); //-------------------------------------------------------------- } //==================================================================////////////////////////////////////////////////////////////////////////// Member classes : non-inner classes//////////////////////////////////////////////////////////////////////// // TEXT BUFFER CLASS private static class TextBuffer { //////////////////////////////////////////////////////////////////// // Constructors //////////////////////////////////////////////////////////////////// private TextBuffer( boolean sync, int capacity ) { this.sync = sync; if ( sync ) syncBuffer = new StringBuffer( capacity ); else nonSyncBuffer = new StringBuilder( capacity ); } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance methods //////////////////////////////////////////////////////////////////// private Object getBuffer( ) { return ( sync ? syncBuffer : nonSyncBuffer ); } //-------------------------------------------------------------- private int getLength( ) { return ( sync ? syncBuffer.length( ) : nonSyncBuffer.length( ) ); } //-------------------------------------------------------------- private void append( char[] data, int length ) { if ( sync ) syncBuffer.append( data, 0, length ); else nonSyncBuffer.append( data, 0, length ); } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance variables //////////////////////////////////////////////////////////////////// private boolean sync; private StringBuilder nonSyncBuffer; private StringBuffer syncBuffer; } //==================================================================////////////////////////////////////////////////////////////////////////// Constructors//////////////////////////////////////////////////////////////////////// public TextFile( File file ) throws IllegalArgumentException, NullPointerException { this( file, Charset.defaultCharset( ).name( ) ); } //------------------------------------------------------------------ public TextFile( File file, String charsetName ) throws IllegalArgumentException, NullPointerException { if ( (file == null) || (charsetName == null) ) throw new NullPointerException( ); if ( charsetName.length( ) == 0 ) throw new IllegalArgumentException( ); this.file = file; this.charsetName = charsetName; progressListeners = new ArrayList<ProgressListener>( ); } //------------------------------------------------------------------////////////////////////////////////////////////////////////////////////// Class methods//////////////////////////////////////////////////////////////////////// public static StringBuilder read( File file ) throws AppException { return new TextFile( file ).read( ); } //------------------------------------------------------------------ public static StringBuilder read( File file, String charsetName ) throws AppException { return new TextFile( file, charsetName ).read( ); } //------------------------------------------------------------------ public static StringBuffer readSync( File file ) throws AppException { return new TextFile( file ).readSync( ); } //------------------------------------------------------------------ public static StringBuffer readSync( File file, String charsetName ) throws AppException { return new TextFile( file, charsetName ).readSync( ); } //------------------------------------------------------------------ public static String[] readLines( File file ) throws AppException { return new TextFile( file ).readLines( ); } //------------------------------------------------------------------ public static String[] readLines( File file, String charsetName ) throws AppException { return new TextFile( file, charsetName ).readLines( ); } //------------------------------------------------------------------ public static String[] readLines( File file, int maxNumLines ) throws AppException { return new TextFile( file ).readLines( maxNumLines ); } //------------------------------------------------------------------ public static String[] readLines( File file, String charsetName, int maxNumLines ) throws AppException { return new TextFile( file, charsetName ).readLines( maxNumLines ); } //------------------------------------------------------------------ public static void write( File file, CharSequence text ) throws AppException { new TextFile( file ).write( text ); } //------------------------------------------------------------------ public static void write( File file, String charsetName, CharSequence text ) throws AppException { new TextFile( file, charsetName ).write( text ); } //------------------------------------------------------------------ public static int[] changeLineSeparators( StringBuilder text, boolean count ) { // Initialise result and indexes int[] lineSeparatorCounts = null; int inIndex = 0; int outIndex = 0; int endIndex = text.length( ); //---- Count and change line separators if ( count ) { // Initialise line separator counts lineSeparatorCounts = new int[NUM_LINE_SEPARATOR_TYPES]; // Count and change line separators while ( inIndex < endIndex ) { char ch = text.charAt( inIndex++ ); if ( ch == '\r' ) { if ( (inIndex < endIndex) && (text.charAt( inIndex ) == '\n') ) { ++inIndex; ++lineSeparatorCounts[LineSeparator.CR_LF]; } else ++lineSeparatorCounts[LineSeparator.CR]; ch = '\n'; } else { if ( ch == '\n' ) ++lineSeparatorCounts[LineSeparator.LF]; } text.setCharAt( outIndex++, ch ); } } //---- Change line separators without counting them else { while ( inIndex < endIndex ) { char ch = text.charAt( inIndex++ ); if ( ch == '\r' ) { if ( (inIndex < endIndex) && (text.charAt( inIndex ) == '\n') ) ++inIndex; ch = '\n'; } text.setCharAt( outIndex++, ch ); } } // Set length of text text.setLength( outIndex ); // Return line separator counts return lineSeparatorCounts; } //------------------------------------------------------------------ public static int[] changeLineSeparators( StringBuffer text, boolean count ) { // Initialise result and indexes int[] lineSeparatorCounts = null; int inIndex = 0; int outIndex = 0; int endIndex = text.length( ); //---- Count and change line separators if ( count ) { // Initialise line separator counts lineSeparatorCounts = new int[NUM_LINE_SEPARATOR_TYPES]; // Count and change line separators while ( inIndex < endIndex ) { char ch = text.charAt( inIndex++ ); if ( ch == '\r' ) { if ( (inIndex < endIndex) && (text.charAt( inIndex ) == '\n') ) { ++inIndex; ++lineSeparatorCounts[LineSeparator.CR_LF]; } else ++lineSeparatorCounts[LineSeparator.CR]; ch = '\n'; } else { if ( ch == '\n' ) ++lineSeparatorCounts[LineSeparator.LF]; } text.setCharAt( outIndex++, ch ); } } //---- Change line separators without counting them else { while ( inIndex < endIndex )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -