⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bufferiorequest.java

📁 Java写的文本编辑器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * BufferIORequest.java - I/O request * Copyright (C) 2000 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */package org.gjt.sp.jedit.io;import javax.swing.text.BadLocationException;import javax.swing.text.Element;import javax.swing.text.Segment;import java.io.*;import java.util.zip.*;import java.util.Vector;import org.gjt.sp.jedit.*;import org.gjt.sp.util.*;/** * A buffer I/O request. * @author Slava Pestov * @version $Id: BufferIORequest.java,v 1.1.1.1 2001/09/02 05:38:15 spestov Exp $ */public class BufferIORequest extends WorkRequest{	/**	 * Size of I/O buffers.	 */	public static final int IOBUFSIZE = 32768;	/**	 * Number of lines per progress increment.	 */	public static final int PROGRESS_INTERVAL = 300;	/**	 * Property loaded data is stored in.	 */	public static final String LOAD_DATA = "IORequest__loadData";	/**	 * A file load request.	 */	public static final int LOAD = 0;	/**	 * A file save request.	 */	public static final int SAVE = 1;	/**	 * An autosave request. Only supported for local files.	 */	public static final int AUTOSAVE = 2;	/**	 * An insert file request.	 */	public static final int INSERT = 3;	/**	 * Creates a new buffer I/O request.	 * @param type The request type	 * @param view The view	 * @param buffer The buffer	 * @param session The VFS session	 * @param vfs The VFS	 * @param path The path	 */	public BufferIORequest(int type, View view, Buffer buffer,		Object session, VFS vfs, String path)	{		this.type = type;		this.view = view;		this.buffer = buffer;		this.session = session;		this.vfs = vfs;		this.path = path;		markersPath = vfs.getParentOfPath(path)			+ '.' + vfs.getFileName(path)			+ ".marks";	}	public void run()	{		switch(type)		{		case LOAD:			load();			break;		case SAVE:			save();			break;		case AUTOSAVE:			autosave();			break;		case INSERT:			insert();			break;		}	}	public String toString()	{		String typeString;		switch(type)		{		case LOAD:			typeString = "LOAD";			break;		case SAVE:			typeString = "SAVE";			break;		case AUTOSAVE:			typeString = "AUTOSAVE";			break;		default:			typeString = "UNKNOWN!!!";		}		return getClass().getName() + "[type=" + typeString			+ ",buffer=" + buffer + "]";	}	// private members	private int type;	private View view;	private Buffer buffer;	private Object session;	private VFS vfs;	private String path;	private String markersPath;	private void load()	{		InputStream in = null;		try		{			try			{				String[] args = { vfs.getFileName(path) };				setStatus(jEdit.getProperty("vfs.status.load",args));				setAbortable(true);				setProgressValue(0);				VFS.DirectoryEntry entry = vfs._getDirectoryEntry(					session,path,view);				long length;				if(entry != null)					length = entry.length;				else					length = 0L;				in = vfs._createInputStream(session,path,false,view);				if(in == null)					return;				if(path.endsWith(".gz"))					in = new GZIPInputStream(in);				String lineSeparator = read(buffer,in,length);				buffer.putProperty(Buffer.LINESEP,lineSeparator);				buffer.setNewFile(false);			}			catch(CharConversionException ch)			{				Log.log(Log.ERROR,this,ch);				Object[] pp = { path,					buffer.getProperty(Buffer.ENCODING),					ch.toString() };				VFSManager.error(view,"encoding-error",pp);			}			catch(IOException io)			{				Log.log(Log.ERROR,this,io);				Object[] pp = { path, io.toString() };				VFSManager.error(view,"read-error",pp);			}			if(jEdit.getBooleanProperty("persistentMarkers"))			{				try				{					String[] args = { vfs.getFileName(path) };					setStatus(jEdit.getProperty("vfs.status.load-markers",args));					setAbortable(true);					in = vfs._createInputStream(session,markersPath,true,view);					if(in != null)						readMarkers(buffer,in);				}				catch(IOException io)				{					// ignore				}			}		}		catch(WorkThread.Abort a)		{			if(in != null)			{				try				{					in.close();				}				catch(IOException io)				{				}			}		}		finally		{			try			{				vfs._endVFSSession(session,view);			}			catch(IOException io)			{				Log.log(Log.ERROR,this,io);				String[] pp = { path, io.toString() };				VFSManager.error(view,"read-error",pp);			}			catch(WorkThread.Abort a)			{			}		}	}	/**	 * Reads the buffer from the specified input stream. Read and	 * understand all these notes if you want to snarf this code for	 * your own app; it has a number of subtle behaviours which are	 * not entirely obvious.<p>	 *	 * Some notes that will help future hackers:	 * <ul>	 * <li>	 * We use a StringBuffer because there is no way to pre-allocate	 * in the GapContent - and adding text each time to the GapContent	 * would be slow because it would require array enlarging, etc.	 * Better to do as few gap inserts as possible.	 *	 * <li>The StringBuffer is pre-allocated to the file's size (obtained	 * from the VFS). If the file size is not known, we default to	 * IOBUFSIZE.	 *	 * <li>We read the stream in IOBUFSIZE (= 32k) blocks, and loop over	 * the read characters looking for line breaks.	 * <ul>	 * <li>a \r or \n causes a line to be added to the model, and appended	 * to the string buffer	 * <li>a \n immediately following an \r is ignored; so that Windows	 * line endings are handled	 * </ul>	 *	 * <li>This method remembers the line separator used in the file, and	 * stores it in the lineSeparator buffer-local property. However,	 * if the file contains, say, hello\rworld\n, lineSeparator will	 * be set to \n, and the file will be saved as hello\nworld\n.	 * Hence jEdit is not really appropriate for editing binary files.	 *	 * <li>To make reloading a bit easier, this method automatically	 * removes all data from the model before inserting it. This	 * shouldn't cause any problems, as most documents will be	 * empty before being loaded into anyway.	 *	 * <li>If the last character read from the file is a line separator,	 * it is not added to the model! There are two reasons:	 * <ul>	 * <li>On Unix, all text files have a line separator at the end,	 * there is no point wasting an empty screen line on that	 * <li>Because save() appends a line separator after *every* line,	 * it prevents the blank line count at the end from growing	 * </ul>	 * 	 * </ul>	 */	private String read(Buffer buffer, InputStream _in, long length)		throws IOException	{		// only true if the file size is known		boolean trackProgress = (length != 0);		File file = buffer.getFile();		setProgressValue(0);		setProgressMaximum((int)length);		// if the file size is not known, start with a resonable		// default buffer size		if(length == 0)			length = IOBUFSIZE;		StringBuffer sbuf = new StringBuffer((int)length);		InputStreamReader in = new InputStreamReader(_in,			(String)buffer.getProperty(Buffer.ENCODING));		char[] buf = new char[IOBUFSIZE];		// Number of characters in 'buf' array.		// InputStream.read() doesn't always fill the		// array (eg, the file size is not a multiple of		// IOBUFSIZE, or it is a GZipped file, etc)		int len;		// True if a \n was read after a \r. Usually		// means this is a DOS/Windows file		boolean CRLF = false;		// A \r was read, hence a MacOS file		boolean CROnly = false;		// Was the previous read character a \r?		// If we read a \n and this is true, we assume		// we have a DOS/Windows file		boolean lastWasCR = false;		// Number of lines read. Every 100 lines, we update the		// progress bar		int lineCount = 0;		while((len = in.read(buf,0,buf.length)) != -1)		{			// Offset of previous line, relative to			// the start of the I/O buffer (NOT			// relative to the start of the document)			int lastLine = 0;			for(int i = 0; i < len; i++)			{				// Look for line endings.				switch(buf[i])				{				case '\r':					// If we read a \r and					// lastWasCR is also true,					// it is probably a Mac file					// (\r\r in stream)					if(lastWasCR)					{						CROnly = true;						CRLF = false;					}					// Otherwise set a flag,					// so that \n knows that last					// was a \r					else					{						lastWasCR = true;					}					// Insert a line					sbuf.append(buf,lastLine,i -						lastLine);					sbuf.append('\n');					if(trackProgress && lineCount++ % PROGRESS_INTERVAL == 0)						setProgressValue(sbuf.length());					// This is i+1 to take the					// trailing \n into account					lastLine = i + 1;					break;				case '\n':					// If lastWasCR is true,					// we just read a \r followed					// by a \n. We specify that					// this is a Windows file,					// but take no further					// action and just ignore					// the \r.					if(lastWasCR)					{						CROnly = false;						CRLF = true;						lastWasCR = false;						// Bump lastLine so						// that the next line						// doesn't erronously						// pick up the \r						lastLine = i + 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -