2015-06-13 3 views
0

Я пытаюсь использовать API файловой системы в приложении Chrome. Я пробовал весь образец кода, который я могу найти, и не могу получить простой текстовый файл для чтения. Я регистрируюсь почти на каждом шаге, и, похоже, что происходит (или не происходит), все останавливается в первый раз, когда я ссылаюсь на объект считывателя файлов. Он создает просто отлично, потому что я могу зарегистрировать .readyState, но после этого я не могу даже установить событие onload() или выполнить .readAsText().Chrome App FileReader

Вот что я звоню из кнопки:

function clickButton(){ 

    chrome.fileSystem.chooseEntry({type: 'openFile', acceptsMultiple: false}, function(FileEntry){ 
    if(chrome.runtime.lastError) {console.warn("Warning: " + chrome.runtime.lastError.message);} 
    else{ 
     console.log(FileEntry); 
     var thing = new FileReader(); 
     console.log(thing.readyState); 
     thing.onloadstart(function(){ 
     console.log("Started loading " & FileEntry); 
     }); 
     console.log("added onloadstart"); 
     console.log(thing.readyState); 
     console.log(thing); 
     thing.readAsText(FileEntry); 
     console.log(thing.readyState); 
     console.log(thing.result); 
    } 
    }); 

    document.getElementById("status").innerHTML = "I did something"; 
} 

Я где-то читал, что Chrome не позволяет получать доступ к локальным файлам, но хромовые приложения кажутся разными. По крайней мере, документация, похоже, предполагает это.

Единственное, что у меня на консоли, это объект FileEntry.

https://developer.chrome.com/apps/app_storage#filesystem

Я использовал пример кода прямо по ссылке выше и до сих пор не могут получить это право. У кого-нибудь еще есть эта проблема или я знаю, что я делаю неправильно?

ответ

0

Существует разница между FileEntry и File. Вам нужно вызвать метод .file() FileEntry. Таким образом, заменить

thing.readAsText(FileEntry); 

с

FileEntry.file(function(File) { 
    thing.readAsText(File) 
}) 

https://developer.mozilla.org/en-US/docs/Web/API/FileEntry#File

+0

Это казалось ключом. Это заняло немного (хорошо, много) больше, чем просто это изменение, но оно, наконец, работает. Я о головокружении преследую все обратные вызовы в моем коде. :-) – Nerd1

0

Попробуйте этот код ...

<!doctype html> 
<html> 
<script> 
function handle_files(files) { 
    for (i = 0; i < files.length; i++) { 
    file = files[i] 
    console.log(file) 
    var reader = new FileReader() 
    ret = [] 
    reader.onload = function(e) { 
     console.log(e.target.result) 
    } 
    reader.onerror = function(stuff) { 
     console.log("error", stuff) 
     console.log (stuff.getMessage()) 
    } 
    reader.readAsText(file) //readAsdataURL 
    } 

} 
</script> 
<body> 
FileReader that works! 
<input type="file" multiple onchange="handle_files(this.files)"> 
</body> 
</html> 
+1

Не работает. Приложения Chrome не позволят сценарию в HTML. https://developer.chrome.com/apps/contentSecurityPolicy Я вытащил скрипт в файл .js, чтобы попробовать. Это немного лаяло на меня, потому что ему не нравилась идея определения функции внутри цикла, но она позволяла мне запускать ее. Тем не менее, никаких результатов. Ничего в консольном журнале. Я добавил строку для записи .readyState после readAsText и все еще ничего в журнале. – Nerd1

0

Я написал функцию для извлечения текста из файла.

function getFileEntryText(fileEntry) { 
    return new Promise(function (resolve, reject) { 
     fileEntry.file(function (file) { 
     var fileReader = new FileReader(); 
     fileReader.onload = function (text) { 
      resolve(fileReader.result); 
     }; 
     fileReader.onerror = function() { 
      reject(fileReader.error); 
     }; 
     fileReader.readAsText(file); 
     }); 
    }); 
    } 

Вы можете вызвать этот метод следующим образом:

getFileEntryText(fileEntry).then(function(text) { 
     // Process the file text here 
}, function(error) { 
    // Handle the file error here 
}); 

Одна вещи, я борюсь с при работе с файловой системой является то, что каждый вызов является асинхронным. Наличие нескольких уровней вложенных обратных вызовов может сделать для кода, который трудно читать. В настоящее время я работаю над этим, превращая все, что могу, в обещание.

0

для всех, кто заинтересован, вот мой окончательный (рабочий) код, в комплекте со всеми консолями.log() мне нужно было следить за всеми этими обратными вызовами.

var chosenEntry = null; 

function clickButton(){ 
    console.log("Button clicked"); 
    var accepts = [{ 
     mimeTypes: ['text/*'], 
     extensions: ['js', 'css', 'txt', 'html', 'xml', 'tsv', 'csv', 'rtf'] 
    }]; 
    chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(theEntry) { 
     if (!theEntry) { 
     output.textContent = 'No file selected.'; 
     return; 
     } 
     // use local storage to retain access to this file 
     chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)}); 
     console.log("local data set. calling loadFileEntry"); 
     loadFileEntry(theEntry); 
     console.log("loadFileEntry called, returned to clickButton()"); 
    }); 
} 

function loadFileEntry(_chosenEntry) { 
    console.log("entered loadFileEntry()"); 
    chosenEntry = _chosenEntry; 
    chosenEntry.file(function(file) { 
    readAsText(chosenEntry, function(result) { 
     console.log("running callback in readAsText"); 
     document.getElementById('text').innerHTML = result; 
     console.log("I just tried to update textarea.innerHTML"); 
    }); 
    }); 
    console.log("added function to chosenEntry.file()"); 
} 

function readAsText(fileEntry, callback) { 
    console.log("readAsText called"); 
    fileEntry.file(function(file) { 
    var reader = new FileReader(); 
    console.log("Created reader as FileReader"); 
    reader.onload = function(e) { 
     console.log("called reader.onload function"); 
     callback(e.target.result); 
    }; 
    console.log("calling reader.readAsText"); 
    reader.readAsText(file); 
    }); 
}