Win10系列:JavaScript写入和读取文件
正如上面的内容中所提到的,文件保存选取器用于保存文件,通过Windows.Storage.Pickers命名空间中的FileSavePicker类的pickSaveFileAsync函数可以向指定的文件系统位置中保存一个文件。文件保存之后,还可以对其进行读写操作,如果是向文件中写入内容,可以使用Windows.Storage.FileIO类中的writeTextAsync(file, contents)函数或appendTextAsync(file,contents)函数来实现,参数file表示需要向其中写入内容的文件,contents代表要写入的内容,writeTextAsync函数会将新写入的内容代替文件原来的内容,而appendTextAsync函数是把新内容追加到原来的内容上。如果要从文件中读取内容,可以使用FileIO类中的readTextAsync(file)函数来实现,参数file表示需要被读取的文件。
下面以一个应用程序为例来演示如何对文件进行读写操作,这个应用程序可以实现保存一个文件,也可以向文件中写入内容和读取其中的内容。
新建一个JavaScript的Windows应用商店的空白应用程序项目,将其命名为FileAccessApplication。打开default.html文件,在body元素中添加两个div元素,并在第一个div元素中添加一个h2元素、一个文本区和三个按钮,其中h2元素用来显示页面标题"写入和读取文件示例",文本区用来编辑向文件中写入的内容,三个按钮为"新建一个文件"、"写内容"和"读内容",分别用于新建文件、向文件中写入内容和读取文件中的内容;在第二个div元素中添加两个p元素,其中一个用来显示提示信息,另一个用于显示已读取的文件内容。相应的HTML代码片段如下所示:
<body>
<div>
<h2 class="articleTitle">写入和读取文件示例</h2>
<textarea rows="5" cols="10" id="textareaID"></textarea>
<br />
<button id="createFileButton" class="action1">新建一个文件</button>
<button id="writeFileButton" class="action2">写内容</button>
<button id="readFileButton" class="action3">读内容</button>
<br />
</div>
<div>
<p id="notice"></p>
<p id="readText"></p>
</div>
</body>
在上面的代码中,为了便于设计CSS样式和检索控件,在添加控件时为其设置了类名和ID。其中,设置"新建一个文件"、"写内容"和"读内容"三个按钮的class属性值分别为action1、action2和action3,id属性值分别为createFileButton、writeFileButton和readFileButton,并设置h2元素的class属性值为articleTitle,同时设置textarea控件和两个p元素的id属性值分别为textarea ID、notice和readText。
为了控制应用程序界面的显示外观,在default.css文件中添加如下代码来控制default.html页面的布局。
/*设置h2元素在应用程序界面中的显示位置*/
.articleTitle {
margin: 20px 15px 10px 70px;
}
/*设置textarea控件在界面中的显示位置*/
#textareaID {
margin: 20px 15px 10px 50px;
}
/*设置"新建一个文件"按钮和两个p元素在界面中的显示位置*/
.action1, #notice, #readText {
margin: 20px 15px 10px 30px;
}
/*设置"写内容"按钮在界面中的显示位置*/
.action2 {
margin: 20px 15px 10px 0px;
}
完成前台界面的布局后,应用程序界面效果如图19-19所示。
图19-19 前台界面效果图
布局好前台界面后,接下来介绍如何新建一个文件、向文件中写入内容以及读取文件中的内容。双击打开default.js文件,首先定义一个temporaryFile变量并初始化为null,用于保存新建的文件,以便对其进行读写操作,同时定义一个命名空间NameSpaceSample,并把temporaryFile变量添加到命名空间NameSpaceSample内。代码如下所示:
var temporaryFile = null;
WinJS.Namespace.define("NameSpaceSample", {
sampleFile: temporaryFile
});
在上面的代码中,将sampleFile指定为temporaryFile变量的别名,这样就可以通过命名空间和别名来引用temporaryFile变量,引用方法是NameSpaceSample.sampleFile。
下面在"args.setPromise(WinJS.UI.processAll());"语句后添加如下代码,分别为"新建一个文件"按钮、"写内容"按钮和"读内容"按钮注册click事件处理函数。
document.getElementById("createFileButton").addEventListener("click", CreateFile);
document.getElementById("writeFileButton").addEventListener("click", WriteFile);
document.getElementById("readFileButton").addEventListener("click", ReadFile);
首先以"createFileButton"为参数调用document对象的getElementById函数来查找id属性值为createFileButton的元素对象,并调用addEventListener函数为该元素对象的click事件注册事件处理函数CreateFile,之后通过相同的方法为id属性值分别为writeFileButton和readFileButton的元素对象注册名为WriteFile和ReadFile的click事件处理函数。下面分别来介绍事件处理函数CreateFile、WriteFile和ReadFile的实现代码。
CreateFile函数用来处理"新建一个文件"按钮的单击事件,实现新建一个文件。该函数的代码添加在default.js文件的"app.onactivated = function (args) {...};"语句后,对应的JavaScript代码片段如下所示:
function CreateFile() {
// 首先判断应用程序是否能够调用文件选取器
var currentState = Windows.UI.ViewManagement.ApplicationView.value;
if (currentState === Windows.UI.ViewManagement.ApplicationViewState.snapped &&
!Windows.UI.ViewManagement.ApplicationView.tryUnsnap()) {
//如果文件选取器调用失败,则直接退出程序
return;
}
//新建一个文件保存选取器对象
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
//将文件保存选取器的起始位置设置为文档库
savePicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.documentsLibrary;
// 设置文件类型筛选
savePicker.fileTypeChoices.insert("Plain Text", [".txt"]);
savePicker.fileTypeChoices.insert("Word Document", [".doc"]);
savePicker.fileTypeChoices.insert("Word Document", [".docx"]);
// 设置文件的默认名称
savePicker.suggestedFileName = "New Document";
//调用pickSaveFileAsync函数来创建文件
savePicker.pickSaveFileAsync().then(function (file) {
//判断文件是否创建成功
if (file) {
//如果创建成功,给出相应的成功信息
notice.innerText = "文件 '" + file.name + "' 创建成功.";
//并将创建的文件保存到NameSpaceSample.sampleFile中,以便对其进行读写操作
NameSpaceSample.sampleFile = file;
} else {
//在文件选取器界面中,未创建文件而提前结束了操作
notice.innerText = "没有创建文件,操作取消了!";
}
});
}
在上面的代码中,首先通过Windows.UI.ViewManagement.ApplicationView.value获取应用程序的当前状态,如果应用程序正处于贴靠状态而且尝试取消贴靠失败,那么就不能显示文件选取器,程序停止向下执行。否则新建一个FileSavePicker类的对象savePicker作为文件保存选取器,通过savePicker对象的suggestedStartLocation属性设置文件保存选取器的起始位置为文档库,并使用fileTypeChoices属性获得选取器能够显示的文件类型集合,通过insert函数将.txt、.doc和.docx三种文件类型添加到集合中,接着使用suggestedFileName属性设置文件的默认名称为"New Document"。最后调用savePicker对象的pickSaveFileAsync函数来保存文件,pickSaveFileAsync函数调用完成之后定义一个匿名函数,在匿名函数中对参数file进行判断,如果file不是空对象,说明成功地创建了一个文件,那么在应用程序界面中显示相应的提示信息,并将file文件保存到NameSpaceSample.sampleFile中,如果file为空对象,说明没有创建文件,则在应用程序界面中显示"没有创建文件,操作取消了!"。
WriteFile函数用来处理"写内容"按钮的单击事件,实现向刚创建的文件中写入内容。该函数的代码添加在CreateFile函数后,对应的JavaScript代码片段如下所示:
function WriteFile() {
if (NameSpaceSample.sampleFile!== null) {
//从文本区中获取要向文件中写入的内容
var textArea = document.getElementById("textareaID");
var userContent = textArea.innerText;
//把获取到的文本内容写入文件中,并根据操作结果给出相应的提示信息
if (userContent !== "") {
Windows.Storage.FileIO.appendTextAsync(NameSpaceSample.sampleFile, userContent).done(function () {
//成功地向文件中写入内容
notice.innerText = "文本区中的内容已经被写到文件 '" + NameSpaceSample.sampleFile.name + "' 中了.";
});
}
else {
//写入空内容
notice.innerText = "文本区中的内容是空的,请先输入内容,然后再单击 '写内容' 按钮将内容写入到文件中!";
}
}
else {
//未先创建文件,就进行了写操作
notice.innerText = "文件还不存在,请先创建文件!";
}
}
代码中对NameSpaceSample.sampleFile进行判断,如果NameSpaceSample.sampleFile是空对象,说明要向其中写入内容的文件不存在,则在应用程序界面中显示"文件还不存在,请先创建文件!"。如果NameSpaceSample.sampleFile不是空对象,说明文件已经存在,那么以"textareaID"为参数调用document对象的getElementById函数来查找id属性值为textareaID的元素对象,并赋值给变量textArea,通过textArea变量调用该元素对象的innerText属性来获取要向文件中写入的内容,保存到变量userContent中,并对userContent变量进行判断,如果变量userContent为空,则在应用程序界面中显示"文本区中的内容是空的,请先输入内容,然后再单击 '写内容' 按钮将内容写入到文件中!",如果变量userContent不为空,则以NameSpaceSample.sampleFile和userContent为参数调用FileIO类的appendTextAsync函数将内容userContent写入到文件NameSpaceSample.sampleFile中。appendTextAsync函数调用完成后定义一个匿名函数,用于在应用程序界面中显示相应的提示信息。
ReadFile函数用来处理"读内容"按钮的单击操作,实现从文件中读取内容。该函数的代码添加在WriteFile函数后,相应的JavaScript代码片段如下所示:
function ReadFile() {
if (NameSpaceSample.sampleFile!== null) {
//从文件中读取内容,并根据操作结果给出相应的提示信息
Windows.Storage.FileIO.readTextAsync(NameSpaceSample.sampleFile).done(function (fileContent) {
if(fileContent === ""){
//空文件,给出相应的提示信息
notice.innerText = "文件中的内容是空的!"
}else{
//文件不空,也给出相关的提示信息并显示读取的内容
notice.innerText = "文件 '" + NameSpaceSample.sampleFile.name + "'中的内容为:";
readText.innerText = fileContent;}
});
}
}
在上面的代码中,先对NameSpaceSample.sampleFile进行判断,如果NameSpaceSample.sampleFile不是空对象,说明要读取的文件存在,那么以NameSpaceSample.sampleFile为参数调用FileIO类的readTextAsync函数来从文件NameSpaceSample.sampleFile中读取内容,readTextAsync函数调用完成后定义一个匿名函数,在这个匿名函数中对参数fileContent进行判断,如果fileContent为空,则将id属性值为notice的元素对象的innerText属性赋值为"文件中的内容是空的!",如果fileContent不为空,将fileContent赋值给id属性值为readText的元素对象的innerText属性,从而在应用程序界面中显示读取的文件内容。
启动调试,单击"新建一个文件"按钮,会显示文件选取器窗口,这里在文档库中采用默认名称新建一个文本文件,如图19-20所示。文件的类型和名称确定之后,单击"保存"按钮,会返回到应用程序界面,界面中会显示"文件 'New Document.txt' 创建成功.",这样就成功创建并保存了这个文件。然后,在文本区中输入"这是一个新建文件、写入和读取文件的例子。",单击"写内容"按钮,就将文本区中的内容写入到了刚才创建的文件中,同时界面上会显示提示信息"文本区中的内容已经被写到文件'New Document.txt' 中了.",效果如图19-21所示。如果想读取文件中的内容,单击"读内容"按钮,文件中的内容就会显示在界面下方,效果如图19-22所示。
图19-20 文件选取器界面
图19-21 成功向文件中写入内容的效果
图19-22 成功读取文件内容的效果