3

我已经阅读了很多关于文件系统 API 和 HTML5 的内容,但是我找不到一个可行的解决方案,所以我问你们:

我想要一个文件上传表单,拖放或常规输入框无关紧要,但是我想选择一个文件,上传后应该将文件或整个文件夹“上传”到位于客户端的文件系统计算机。上传在括号中,因为我实际上想将文件/文件夹复制到客户端本地文件系统。

甚至可能吗?因为我想制作一个应用程序,用户可以将他的文件(例如音乐或大型视频和电影)上传到他的本地文件系统并在我的应用程序中编辑/观看等。我知道我必须上传那些大文件,我必须将它们切成小块并将它们堆叠起来,但我只想从小事开始:)

提前致谢

4

2 回答 2

4

目前关于这个主题的信息确实很少,所以我整理了一个例子,它结合了:

  • 使用 上的webkitdirectory属性<input type="file">
    • 这允许用户使用适当的对话框来选择目录。
  • 使用文件系统 API。
    • 这是关于沙盒文件系统,它允许您将文件存储在客户端机器上。
  • 使用文件 API。
    • 这是允许您读取文件的 API。这些文件可以通过一个<input type="file">元素、通过使用拖放的传输或通过 Filesystem API 来访问。

由于这些目前仅在 Chrome 中运行良好,因此我webkit在必要时使用了前缀。

http://jsfiddle.net/zLna6/3/

代码本身有我希望清楚的注释:

var fs,
    err = function(e) {
        throw e;
    };

// request the sandboxed filesystem
webkitRequestFileSystem(
    window.TEMPORARY,
    5 * 1024 * 1024,
    function(_fs) {
        fs = _fs;
    },
    err
);

// when a directory is selected
$(":file").on("change", function() {
    $("ul").empty();

    // the selected files
    var files = this.files;
    if(!files) return;

    // this function copies the file into the sandboxed filesystem
    function save(i) {
        var file = files[i];

        var text = file ? file.name : "Done!";

        // show the filename in the list
        $("<li>").text(text).appendTo("ul");

        if(!file) return;

        // create a sandboxed file
        fs.root.getFile(
            file.name,
            { create: true },
            function(fileEntry) {
                // create a writer that can put data in the file
                fileEntry.createWriter(function(writer) {
                    writer.onwriteend = function() {
                        // when done, continue to the next file
                        save(i + 1);
                    };
                    writer.onerror = err;

                    // this will read the contents of the current file
                    var fr = new FileReader;
                    fr.onloadend = function() {
                        // create a blob as that's what the
                        // file writer wants
                        var builder = new WebKitBlobBuilder;
                        builder.append(fr.result);
                        writer.write(builder.getBlob());
                    };
                    fr.onerror = err;
                    fr.readAsArrayBuffer(file);
                }, err);
            }, 
            err
        );
    }

    save(0);
});

$("ul").on("click", "li:not(:last)", function() {
    // get the entry with this filename from the sandboxed filesystem
    fs.root.getFile($(this).text(), {}, function(fileEntry) {
        // get the file from the entry
        fileEntry.file(function(file) {
            // this will read the contents of the sandboxed file
            var fr = new FileReader;
            fr.onloadend = function() {
                // log part of it
                console.log(fr.result.slice(0, 100));
            };
            fr.readAsBinaryString(file);
        });
    }, err);
});
于 2012-05-23T14:47:48.053 回答
1

确切地说,这是不可能的,但您的应用程序可能仍然可以工作。可以通过文件输入表单元素读取文件,但是将文件写回磁盘是您遇到麻烦的地方。

您的浏览器可以写入磁盘的两种方式是 1) 下载文件和 2) HTML5 文件系统 API。选项 #1 显然不允许您的应用程序选择目标,选项 #2 仅适用于浏览器创建的沙箱文件系统。这个限制对你来说可能不会破坏交易——它只是意味着你的应用程序使用的文件夹将被埋在浏览器数据文件的某个地方。

此外,文件系统 API 目前仅适用于 Chrome(但它是一个开放标准)。如果您想要跨平台支持,也许您可​​以使用IndexedDB。您可以使用 localStorage,但 Chrome 有 5MB 的硬性限制,这对于媒体应用程序来说太糟糕了。

于 2012-05-23T13:41:44.867 回答