我找不到这种情况的任何例子,所以我们开始吧:
我希望用户选择一个目录,加载其中的所有文件,更改它们,然后保存此文件以覆盖它或在同一目录中保存一个新文件,而不询问他要保存的位置。
我相信这是可能的,因为我在这里看到了类似的东西(最后一段):
http://www.developer.com/lang/using-the-file-api-outside-the-sandbox-in-chrome-packaged-apps.html
任何答案将不胜感激,谢谢
编辑:感谢 Chris Johnsen 给了我这个很好的答案:
var fileHandler = function() {
var _entry = null;
this.open = function(cb) {
chrome.fileSystem.chooseEntry({
type: 'openDirectory'
}, function(dirEntry) {
if (!dirEntry || !dirEntry.isDirectory) {
cb && cb(null);
return;
}
_entry = dirEntry;
listDir(_entry, cb);
});
};
this.save = function(filename, source) {
chrome.fileSystem.getWritableEntry(_entry, function(entry) {
entry.getFile(filename, {
create: true
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(new Blob([source], {
type: 'text/javascript'
}));
});
});
});
};
this.saveAs = function(filename, source) {
chrome.fileSystem.chooseEntry({
type: 'openDirectory'
}, function(entry) {
chrome.fileSystem.getWritableEntry(entry, function(entry) {
entry.getFile(filename, {
create: true
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(new Blob([source], {
type: 'text/javascript'
}));
});
});
});
});
};
var listDir = function(dirent, cb, listing) {
if (listing === undefined) {
listing = [];
}
var reader = dirent.createReader();
var read_some = reader.readEntries.bind(reader, function(ents) {
if (ents.length === 0) {
return cb && cb(listing);
}
var process_some = function(ents, i) {
for (; i < ents.length; i++) {
listing.push(ents[i]);
if (ents[i].isDirectory) {
return listDir(ents[i], process_some.bind(null, ents, i + 1), listing);
}
}
read_some();
};
process_some(ents, 0);
}, function() {
console.error('error reading directory');
});
read_some();
};
};
最佳答案
您的 save
对于您的第二个要求(写入代码选择的文件名而无需其他用户提示),该方法应该可以正常工作(大部分情况见下文),但 open
中有几个错误(至少如问题中所述):
chooseEntry
回调,this !== fileHandler
因为回调是用不同的 this
调用的(可能是背景页面的 window
对象)。您可以通过多种方式解决此问题:
fileHandler
而不是 this
(如果您不将其用作任何类型的原型(prototype))。 .bind(this)
将每个回调函数绑定(bind)到相同的上下文。 var self = this;
在 open
的顶部并使用 self.entry
(等等)在回调中。 cb
为成功案例。也许你有另一种方式来推迟调用(例如)fileHandler.save
(单击某个元素以触发保存?),但添加类似⋮
cb && cb(self.entry);
⋮
在
self.entry = dirEntry
之后使(例如)链接 open
变得容易和 save
:fileHandler.open(function(ent) {
fileHandler.save('newfile','This is the text\nto save in the (possibly) new file.');
});
save
中存在潜在错误: 如果你覆盖了一个现有的文件,那么你需要调用 writer.truncate()
(除非您总是写入比最初保存的文件更多的字节)。⋮
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(…);
⋮
看起来您在文件列表部分有了一个良好的开端。如果您想稍后引用文件列表,那么您可能希望将它们保存在您的对象中,而不是仅仅记录它们;如果您想递归到子目录中,这可能会有点麻烦(并且也不假设
readEntries
第一次调用返回所有内容)。function list_dir(dirent, cb, listing) {
if (listing === undefined) listing = [];
var reader = dirent.createReader();
var read_some = reader.readEntries.bind(reader, function(ents) {
if (ents.length === 0)
return cb && cb(listing);
process_some(ents, 0);
function process_some(ents, i) {
for(; i < ents.length; i++) {
listing.push(ents[i]);
if (ents[i].isDirectory)
return list_dir(ents[i], process_some.bind(null, ents, i + 1), listing);
}
read_some();
}
}, function() {
console.error('error reading directory');
});
read_some();
}
您可以在
open
中使用它回调(假设您添加了它的成功回调),如下所示:fileHandler.open(function(ent) {
ent && list_dir(ent, function(listing) {
fileHandler.listing = listing;
console.log('listing', fileHandler.listing.map(function(ent){return ent.fullPath}).join('\n'));
fileHandler.save('a_dir/somefile','This is some data.');
});
});
关于google-chrome-app - 使用 Chrome FileSystem,让用户选择一个目录,在里面加载文件。并将文件保存在该目录中而无需再次提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21896363/