我找不到这个场景的任何例子,所以我们走了:
我希望用户选择一个目录,加载其中的所有文件,更改它们,并保存此文件覆盖它或将新文件保存在同一目录中,而不询问他想要保存的位置。
我相信这是可能的,因为我在这里看到类似的东西(最后一段): 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();
};
};
答案 0 :(得分:5)
您的save
方法应该可以正常工作(大多数情况下见下文)以满足您的第二个要求(在没有其他用户提示的情况下写入代码选择的文件名),但open
中存在一些错误(至少在问题中提出):
chooseEntry
回调中this !== fileHandler
,因为回调是使用不同的this
(可能是背景页的window
对象)调用的。fileHandler
代替this
(如果您没有将其用作任何原型)。.bind(this)
将每个回调函数绑定到同一个上下文。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.');
});
});