在Javascript中同步读取文件
Read a file synchronously in Javascript
我想读取一个文件,并使用FileReader对象将其转换为base64编码的字符串。下面是我使用的代码:
<>之前var reader = new FileReader();读者。Onloadend = function(evt) {//文件被加载Result_base64 = evt.target.result;};reader.readAsDataURL(文件);之前但是在这种情况下,我在事件处理程序(onLoadEnd事件)中获得转换的结果。我想要一个同步方法。是否有一种方法"readAsDataURL"方法可以直接返回"result_base64"变量的值?
你可以使用标准的FileReaderSync,这是一个更简单的,同步的,阻塞版本的FileReader API,类似于你已经使用的:
let reader = new FileReaderSync();
let result_base64 = reader.readAsDataURL(file);
console.log(result_base64); // aGV5IHRoZXJl...
请记住,由于显而易见的原因,只能在工作线程中使用。
如果你需要一个主线程"读起来像"的解决方案一个同步的API,即顺序地,你可以把异步的FileReader包装在一个promise中,并使用异步函数(你可能需要转换):
async function readFileAsDataURL(file) {
let result_base64 = await new Promise((resolve) => {
let fileReader = new FileReader();
fileReader.onload = (e) => resolve(fileReader.result);
fileReader.readAsDataURL(file);
});
console.log(result_base64); // aGV5IHRoZXJl...
return result_base64;
}
然后你可以在另一个异步上下文中等待这个函数:
async function main() {
let file = new File(...)
let dataURL = await readFileAsDataURL(file)
console.log(dataURL); // aGV5IHRoZXJl...
}
…或者直接使用promise回调(不需要async上下文):
readFileAsDataURL(file).then(dataURL => {
console.log(dataURL); // aGV5IHRoZXJl...
});
同步任务(阻塞)通常不好。如果没有真正的理由同步执行,我强烈建议您使用事件回调。
想象一下你的文件坏了,HTML5 api无法读取,它不会给你结果。它会破坏你的代码并封锁网站。或者,有人可以选择一个10GB的文件,这将冻结您的HTML页面,直到文件完全加载。使用异步事件处理程序,您可以捕获可能的错误。
为了解决回调的限制,我使用了一个简单的技巧:var ready = false;
var result = '';
var check = function() {
if (ready === true) {
// do what you want with the result variable
return;
}
setTimeout(check, 1000);
}
check();
var reader = new FileReader();
reader.onloadend = function(evt) {
// file is loaded
result = evt.target.result;
ready = true;
};
reader.readAsDataURL(file);
check函数,每秒检查ready标志变量是否设置为true。如果是,则可以确定结果是可用的。
这样做可能不是最佳实践,但我用这种技术做了一个web应用程序,大约30次,同时运行了10多个settimeout,直到现在还没有遇到任何问题。
自2022年11月1日起,file.getAsDataURL()已过时,这是唯一的直接同步方法。只需将File对象传递给下面的函数,该函数将返回一个数据url。
readSyncDataURL=function(file){
var url=URL.createObjectURL(file);//Create Object URL
var xhr=new XMLHttpRequest();
xhr.open("GET",url,false);//Synchronous XMLHttpRequest on Object URL
xhr.overrideMimeType("text/plain; charset=x-user-defined");//Override MIME Type to prevent UTF-8 related errors
xhr.send();
URL.revokeObjectURL(url);
var returnText="";
for (var i=0;i<xhr.responseText.length;i++){
returnText+=String.fromCharCode(xhr.responseText.charCodeAt(i)&0xff);};//remove higher byte
return "data:"+file.type+";base64,"+btoa(returnText);}//Generate data URL
下一个函数只是一个通用函数,将File对象转换为二进制字符串(以防有人正在搜索它):
readSyncBinaryString=function(file){
var url=URL.createObjectURL(file);//Create Object URL
var xhr=new XMLHttpRequest();
xhr.open("GET",url,false);//Synchronous XMLHttpRequest on Object URL
xhr.overrideMimeType("text/plain; charset=x-user-defined");//Override MIME Type to prevent UTF-8 related errors
xhr.send();
URL.revokeObjectURL(url);
var returnText="";
for (var i=0;i<xhr.responseText.length;i++){
returnText+=String.fromCharCode(xhr.responseText.charCodeAt(i)&0xff);};//remove higher byte
return returnText;}
如果你需要一个ArrayBuffer,使用这个函数:
readSyncArrayBuffer=function(file){
var url=URL.createObjectURL(file);
var xhr=new XMLHttpRequest();
xhr.open("GET",url,false);//Synchronous XMLHttpRequest on Object URL
xhr.overrideMimeType("text/plain; charset=x-user-defined");//Override MIME Type to prevent UTF-8 related errors
xhr.send();
URL.revokeObjectURL(url);
var returnArray=[];
for (var i=0;i<xhr.responseText.length;i++){
returnArray.push(xhr.responseText.charCodeAt(i)&0xff);};//remove higher byte
return new Uint8Array(returnArray).buffer;}//Generate Buffer
下面的代码同步读取文件
function SyncFileReader(file) {
let self = this;
let ready = false;
let result = '';
const sleep = function (ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
self.readAsArrayBuffer = async function() {
while (ready === false) {
await sleep(100);
}
return result;
}
const reader = new FileReader();
reader.onloadend = function(evt) {
result = evt.target.result;
ready = true;
};
reader.readAsArrayBuffer(file);
}
用法:
const fileReader = new SyncFileReader(file);
const arrayBuffer = await fileReader.readAsArrayBuffer();
我偶然发现了这个线程,因为我正在寻找一种直接的方法来等待,直到文件在async函数中读取。下面是我的解决方案:
const reader = new FileReader()
function readFile (file) {
return new Promise((resolve, reject) => {
reader.onload = (event) => {
resolve(event.target.result)
}
reader.onerror = (event) => {
reject(event.target.error)
}
reader.readAsArrayBuffer(file) // change this if you want to read the file as e.g. text
})
}
用法是直接的:
async function whatever() {
let content = await readFile(your_file)
}
快乐己菌素'
使用fs.readFileSync命令同步读取文件内容
var fs = require('fs');
var content = fs.readFileSync('myfilename');
console.log(content);
fs。createReadStream创建一个读流。
下面的代码以同步方式读取文件并将其内容作为text (string)返回
function SyncFileReader(file) {
let self = this;
let ready = false;
let result = '';
const sleep = function (ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
self.readAsDataURL = async function() {
while (ready === false) {
await sleep(100);
}
return result;
}
const reader = new FileReader();
reader.onloadend = function(evt) {
result = evt.target.result;
ready = true;
};
reader.readAsDataURL(file);
}
用法:
const fileReader = new SyncFileReader(file);
const arrayBuffer = await fileReader.readAsDataURL();
在Node.js中,使用child_process
中的execSync
,并让shell同步读取它。将子进程的输出重定向到父进程。
// Don't forget to use your favorite encoding in toString()
var execSync = require('child_process').execSync;
var fileContents = execSync('cat path/to/file.txt', {stdio: "pipe"}).toString();
我很高兴接受你对uoc奖的提名。div;)
- 使用JS/NodeJS测试并读取文件中的变量
- 当读取文件时,浏览器打开良好,但它是空白浏览器
- 当尝试使用ajax读取文件时,变量返回undefined
- 用一些像jsBin/jsFiddle/codePen这样的工具读取文件
- 在Windows Metro风格的Javascript应用程序中读取文件内容
- 咕噜声.js无法读取文件(错误代码:EISDIR)
- 如何从文件夹中读取文件
- Javascript - 如何读取文件
- 如何从 Duktape 中运行的 JavaScript 代码中读取文件
- 当客户端是服务器时,使用 client-JS 读取文件结构
- 如何从chrome扩展名读取文件
- 为什么“;readFile”;使用比读取文件更多的内存's的内容长度
- 在html中读取文件
- 使用javascript读取文件
- 节点尝试在同步写入完成之前读取文件
- 无法通过FileReader读取文件
- 从php中的本地磁盘读取文件
- 使用Javascript读取文件
- 是否可以使用 javascript 从目录中读取文件
- 通过网络浏览器从 URL javascript 读取文件