65.9K
CodeProject 正在变化。 阅读更多。
Home

Scratchpad:自动保存的记事本

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (9投票s)

2007年3月27日

CPOL

2分钟阅读

viewsIcon

55361

downloadIcon

1072

Scratchpad 是一个非常简单的类似记事本的编辑器,它每 5 分钟自动保存一次,并在应用程序关闭时自动保存。

Screenshot - scratchpad.jpg

背景

我总是喜欢打开一个文本编辑器窗口,在里面写下任何浮现在脑海中的想法。但有时我在关机时忘记保存这段文字,从而丢失了我写的所有内容。

为了避免这个问题,我编写了 scratchpad,这是一个非常简单的文本编辑器,可以在应用程序关闭时自动保存。

特点

Scratchpad 支持以下功能

  1. 当应用程序启动时,它会自动重新打开最后编辑的文件,并恢复窗口的位置、大小和状态。
  2. 当应用程序关闭时,以及每 5 分钟,编辑的文件都会被保存。
  3. 为了能够在计算机在保存操作期间崩溃时恢复文本,会创建一个备份文件。

代码

窗口位置和最后打开文件的持久化

需要使以下信息持久化:

  • 窗口位置
  • 窗口大小(在正常状态下)
  • 窗口状态(最大化/最小化/正常)
  • 编辑文件的名称

为了实现这种持久化,我创建了一个可序列化类(PersistentData),用作包含所有需要持久化数据的结构。

[Serializable]
public class PersistentData
    {
    public int Top;
    public int Left;
    public int Width;
    public int Height;
    public string FilePath;
    public FormWindowState WindowState;
    }

要保存 pDataPersistenData 的实例)的内容,我使用 Serialize 方法。

//save the context
//================
pData.WindowState = this.WindowState;

// Force the window to normal size to retrieve normal size bounds
this.WindowState = FormWindowState.Normal;
pData.Top = this.Top;
pData.Left = this.Left;
pData.Width = this.Width;
pData.Height = this.Height;

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(Application.CommonAppDataPath + 
	@"\scratchpad.ini", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, pData );
            stream.Close();

注意 1:保存设置的路径是通过调用 Application.CommonAppDataPath 获取的。

注意 2:为了避免保存“最大化”的大小,在读取其大小和位置之前,窗口会被强制设置为“正常”大小。

要恢复持久化数据,我使用 Deserialize 方法。如果反序列化失败(因为应用程序设置文件不可用),则 pData 将使用默认值进行初始化。

try 
  {
  IFormatter formatter = new BinaryFormatter();
  Stream stream = new FileStream(Application.CommonAppDataPath+@"\scratchpad.ini", 
		FileMode.Open, FileAccess.Read, FileShare.Read);
  pData = (PersistentData)formatter.Deserialize(stream);
  stream.Close();
  }
catch //deserialization failed
  {
  pData = new PersistentData();
  pData.Top = this.Top;
  pData.Left = this.Left;
  pData.Width = this.Width;
  pData.Height = this.Height;
  pData.WindowState = this.WindowState;
  pData.FilePath = "scatch.txt";
  }

每 5 分钟自动保存

每 5 分钟的自动保存是通过一个定时器完成的,该定时器在上次保存后文本被修改时,每 300,000 毫秒触发一次保存操作。

private void timer1_Tick(object sender, EventArgs e)
{
 if (textBox1.Modified)
     {
     Save();
     }
}

请注意,textbox1.modified 标志不会被框架自动设置或清除,也就是说,应用程序必须显式地设置和清除它。

备份文件创建

为了确保数据不会在计算机在保存操作期间崩溃时损坏,我在对编辑的文件执行任何写入操作之前,使用 File.Copy 创建原始文件的副本。注意:用于避免编辑文件尚不存在于磁盘上的问题的 try catch

//
//creates the backup
//===================
try
    {
    File.Copy(pData.FilePath,pData.FilePath+".bak",true);
    }
catch { /* ignore error */ }

// write the file
//=================
using (StreamWriter sw = new StreamWriter(pData.FilePath))
    {
    sw.Write(this.textBox1.Text);
    }

历史

  • 2007 年 3 月 27 日:创建了版本 1.0
© . All rights reserved.