如何阅读本地文本文件?

Dan*_*nny 335 javascript file-io xmlhttprequest

我试图通过创建一个函数来编写一个简单的文本文件阅读器,该函数接收文件的路径并将每行文本转换为char数组,但它不起作用.

function readTextFile() {
  var rawFile = new XMLHttpRequest();
  rawFile.open("GET", "testing.txt", true);
  rawFile.onreadystatechange = function() {
    if (rawFile.readyState === 4) {
      var allText = rawFile.responseText;
      document.getElementById("textSection").innerHTML = allText;
    }
  }
  rawFile.send();
}
Run Code Online (Sandbox Code Playgroud)

这里出了什么问题?

先前版本稍微更改代码后,这似乎仍然无效,现在它给了我一个XMLHttpRequest异常101.

我已经在Firefox上测试了它并且它可以工作,但是在谷歌Chrome中它不会工作并且它一直给我一个例外101.我如何才能让它不仅可以用于Firefox,还可以用于其他浏览器(尤其是Chrome) )?

Maj*_*ssi 283

您需要检查状态0(当在本地加载文件时XMLHttpRequest,您没有返回状态,因为它不是来自a Webserver)

function readTextFile(file)
{
    var rawFile = new XMLHttpRequest();
    rawFile.open("GET", file, false);
    rawFile.onreadystatechange = function ()
    {
        if(rawFile.readyState === 4)
        {
            if(rawFile.status === 200 || rawFile.status == 0)
            {
                var allText = rawFile.responseText;
                alert(allText);
            }
        }
    }
    rawFile.send(null);
}
Run Code Online (Sandbox Code Playgroud)

file://在您的文件名中指定:

readTextFile("file:///C:/your/path/to/file.txt");
Run Code Online (Sandbox Code Playgroud)

  • 这将无法在Chrome(可能性,其他浏览器)中使用"只有协议方案才支持跨源请求:http,数据,chrome,chrome-extension,https,chrome-extension-resource." (126认同)
  • 它不需要是一个绝对的路径..这对我很有用:readTextFile('Properties/version.txt'); 谢谢! (21认同)
  • 尝试将`file:/// User/Danny/Desktop/javascriptWork/testing.txt`放入浏览器的url栏,看看是否可以看到该文件.. (11认同)
  • 如果没有用户交互,这真的有效吗?我无法让它在 Chrome 中工作(没有用户选择文件)。 (3认同)
  • 我实际上在mac上工作,所以我仍然会指定文件:// ?? (2认同)
  • 由于我们正在从网络服务器上阅读,我们应该将异步设置为"true".如果这是一个简单的`local`搜索,那么将async设置为`false`就可以了,但是当设置为false时不需要`onreadystatechange`.这是文档:http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp (2认同)
  • 我收到一条警告,说这已被弃用:/关于替代方法的任何建议? (2认同)
  • 在 Chrome 中不起作用。FireFox 还抛出一个错误:“主线程上的同步 XMLHttpRequest 已被弃用” (2认同)
  • 对于所有需要良好答案的用户:`fetch("myText.txt", {mode: "no-cors"}).then(res => res.text()).then(text => doSomethingWithText(text) )` (2认同)

Ami*_*sia 90

访问Javascripture!然后转到readAsText部分并尝试示例.您将能够了解FileReaderreadAsText函数的工作原理.

    <html>
    <head>
    <script>
      var openFile = function(event) {
        var input = event.target;

        var reader = new FileReader();
        reader.onload = function(){
          var text = reader.result;
          var node = document.getElementById('output');
          node.innerText = text;
          console.log(reader.result.substring(0, 200));
        };
        reader.readAsText(input.files[0]);
      };
    </script>
    </head>
    <body>
    <input type='file' accept='text/plain' onchange='openFile(event)'><br>
    <div id='output'>
    ...
    </div>
    </body>
    </html>
Run Code Online (Sandbox Code Playgroud)

  • 此示例处理用户输入的文本文件,但我认为问题是关于服务器本地的文件. (14认同)
  • 链接很好,但是如果目标站点无法访问或永久脱机,您应该"始终引用重要链接中最相关的部分." 请参阅[如何撰写一个好的答案](https://stackoverflow.com/help/how-to-answer). (13认同)
  • @S.Kirby 正如OP在回答有关它是在本地还是在远程服务器上运行的问题时所说:[都是本地的。所有内容都在一个文件夹中,没有其他内容。](/sf/ask/1011251321/#comment20120579_14446538)。此外,其他人(比如我)可能会对如何在本地进行操作有疑问。 (2认同)

Abd*_*che 82

在javascript中引入fetch api之后,读取文件内容变得更加简单.

阅读文本文件

fetch('file.txt')
  .then(response => response.text())
  .then(text => console.log(text))
  // outputs the content of the text file
Run Code Online (Sandbox Code Playgroud)

读一个json文件

fetch('file.json')
  .then(response => response.json())
  .then(jsonResponse => console.log(jsonResponse))     
   // outputs a javascript object from the parsed json
Run Code Online (Sandbox Code Playgroud)

更新30/07/2018(免责声明):

这种技术在Firefox中运行良好,但似乎Chromefetch实现file:///在编写此更新之日不支持URL方案(在Chrome 68中测试).

  • `Fetch API无法加载file:/// C:/Users/path/to/file/file.txt.对于CORS请求,URL方案必须是"http"或"https" (10认同)
  • 辉煌!引用获取标准:"提供一致的处理:URL方案,重定向,跨源语义,CSP,服务工作者,混合内容,`Referer`".我想这意味着告别好的ol'FileReaders和HttpRequests(我不会错过它们;) (4认同)
  • 但是如何使用 *text* 并将其放入字符串变量中以便在其他地方使用?(无论我对它做什么,我都会不断得到“未定义”。) (3认同)
  • @ not2qubit获取文本文件是异步操作.您正在获取未定义,因为您在完全读取文件之前使用该变量.你必须在promise回调中使用它或使用类似javascript"async await"运算符. (2认同)
  • 同样是愚蠢的 Chrome 68。我不敢相信这是一个热门话题,感谢 @AbdelazizMokhnache 让我们了解情况。杰克。我刚刚测试了 File-Save.js,它有效,我想要一些简单的方法来读回文件(基本上将我的设置保存/恢复到我选择的文件中) (2认同)

小智 32

var input = document.getElementById("myFile");
var output = document.getElementById("output");


input.addEventListener("change", function () {
  if (this.files && this.files[0]) {
    var myFile = this.files[0];
    var reader = new FileReader();
    
    reader.addEventListener('load', function (e) {
      output.textContent = e.target.result;
    });
    
    reader.readAsBinaryString(myFile);
  }   
});
Run Code Online (Sandbox Code Playgroud)
<input type="file" id="myFile">
<hr>
<textarea style="width:500px;height: 400px" id="output"></textarea>
Run Code Online (Sandbox Code Playgroud)

  • 我不确定这回答了这个4岁的问题.OP不上传文档,他们试图从路径中读取同一目录中的文本文件.如果你要回答这个问题,至少要写一个简短的摘要,说明为什么你认为你的答案现在比其他人好,或者自问题以来语言如何改变以保证新的答案. (7认同)
  • 使用我自己现有的文件上传输入 html - 从 `var reader = new FileReader();` 通过 `reader.readAsBinaryString(..)` 复制行 - 它读取我的文本文件的内容。干净、优雅,就像一种魅力。这个线程中对我来说最好的答案 - 谢谢! (4认同)

joe*_*joe 21

现代解决方案:

使用fileOrBlob.text()方法如下:

<input type="file" onchange="this.files[0].text().then(t => console.log(t))">
Run Code Online (Sandbox Code Playgroud)

当用户通过该输入上传文本文件时,它将被记录到控制台。这是一个有效的 jsbin 演示

这是一个更详细的版本:

<input type="file" onchange="loadFile(this.files[0])">
<script>
  async function loadFile(file) {
    let text = await file.text();
    console.log(text);
  }
</script>
Run Code Online (Sandbox Code Playgroud)

目前(2020 年 1 月)这仅适用于 Chrome 和 Firefox,如果您将来阅读本文,请在此处检查兼容性:https : //developer.mozilla.org/en-US/docs/Web/API/Blob/text

在较旧的浏览器上,这应该有效:

<input type="file" onchange="loadFile(this.files[0])">
<script>
  async function loadFile(file) {
    let text = await (new Response(file)).text();
    console.log(text);
  }
</script>
Run Code Online (Sandbox Code Playgroud)

相关:截至 2020 年 9 月,Chrome 和 Edge 中提供了新的本机文件系统 API,以防您想要对用户选择的文件进行永久读取访问(甚至写入访问)。


Spa*_*row 14

乔恩佩里曼,

是js可以读取本地文件(请参阅FileReader())但不能自动读取:用户必须使用html将文件或文件列表传递给脚本<input type=file>.

然后使用js可以处理(示例视图)文件或文件列表,它们的一些属性以及文件或文件内容.

出于安全原因,js不能做的是自动访问(无需用户输入)到他的计算机的文件系统.

要允许js自动访问本地fs,需要创建一个内部没有js的html文件,而是创建一个hta文档.

一个hta文件里面可以包含js或vbs.

但是hta可执行文件仅适用于Windows系统.

这是标准的浏览器行为.

google chrome也在fs api工作,更多信息来自:http://www.html5rocks.com/en/tutorials/file/filesystem/

  • 这就是我正在寻找的评论。每个人都将用户输入文件的代码作为输入标记,但问题是如何从用户代码中提到的路径自动获取文件。谢谢! (2认同)

小智 13

很可能你已经尝试过,输入"false"如下:

 rawFile.open("GET", file, false);
Run Code Online (Sandbox Code Playgroud)


小智 12

尝试创建两个函数:

function getData(){       //this will read file and send information to other function
       var xmlhttp;

       if (window.XMLHttpRequest) {
           xmlhttp = new XMLHttpRequest();               
       }           
       else {               
           xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");               
       }

       xmlhttp.onreadystatechange = function () {               
           if (xmlhttp.readyState == 4) {                   
             var lines = xmlhttp.responseText;    //*here we get all lines from text file*

             intoArray(lines);     *//here we call function with parameter "lines*"                   
           }               
       }

       xmlhttp.open("GET", "motsim1.txt", true);
       xmlhttp.send();    
}

function intoArray (lines) {
   // splitting all text data into array "\n" is splitting data from each new line
   //and saving each new line as each element*

   var lineArr = lines.split('\n'); 

   //just to check if it works output lineArr[index] as below
   document.write(lineArr[2]);         
   document.write(lineArr[3]);
}
Run Code Online (Sandbox Code Playgroud)


web*_*sky 11

其他例子 - 我的读者使用FileReader类

<html>
    <head>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
    </head>
    <body>
        <script>
            function PreviewText() {
            var oFReader = new FileReader();
            oFReader.readAsDataURL(document.getElementById("uploadText").files[0]);
            oFReader.onload = function (oFREvent) {
                document.getElementById("uploadTextValue").value = oFREvent.target.result; 
                document.getElementById("obj").data = oFREvent.target.result;
            };
        };
        jQuery(document).ready(function(){
            $('#viewSource').click(function ()
            {
                var text = $('#uploadTextValue').val();
                alert(text);
                //here ajax
            });
        });
        </script>
        <object width="100%" height="400" data="" id="obj"></object>
        <div>
            <input type="hidden" id="uploadTextValue" name="uploadTextValue" value="" />
            <input id="uploadText" style="width:120px" type="file" size="10"  onchange="PreviewText();" />
        </div>
        <a href="#" id="viewSource">Source file</a>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

  • 文件返回base64输出 (2认同)

bar*_*o32 10

使用Fetch和 async 函数

const logFileText = async file => {
    const response = await fetch(file)
    const text = await response.text()
    console.log(text)
}

logFileText('file.txt')
Run Code Online (Sandbox Code Playgroud)

  • 我收到“对于 CORS 请求,URL 方案必须是“http”或“https”。” (14认同)

Sam*_* R. 6

这可能有所帮助,

    var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            alert(xmlhttp.responseText);
        }
    }

    xmlhttp.open("GET", "sample.txt", true);
    xmlhttp.send();
Run Code Online (Sandbox Code Playgroud)


Teo*_*cci 6

这个问题可能很老了,但我们需要澄清两个主要想法。我们想一次读取整个文件吗?或者逐行阅读?

Teo,我想获取整个文件并稍后处理。

好吧,这很容易。我们只需要调用Blob.text()方法(请记住,该方法假设文件被编码为UTF-8)并像这样处理文件:

const $output = document.getElementById('output')
const $file = document.getElementById('file')
const fetchFile = async e => {
  const [file] = e.target.files
  const text = await file.text()
  $output.textContent = text
}

$file.onchange = fetchFile
Run Code Online (Sandbox Code Playgroud)
<input id='file' type='file' accept='text/plain'><br>
<pre id='output'>...</pre>
Run Code Online (Sandbox Code Playgroud)

那一行一行的呢?那可能吗?。

是的,我年轻的学徒,这也是可能的。我们只需要调用该 String.split()方法将文本划分为行数组,如下所示:

const $output = document.getElementById('output')
const $file = document.getElementById('file')
let count
const fetchFile = async e => {
  const [file] = e.target.files
  if (!file) return
  count = 0
  const text = await file.text()
  $output.textContent = text

  const lines = text.split(/\r?\n/gm)
  for (const line of lines) {
    if (line) count++
  }
  console.log({count})
}

$file.onchange = fetchFile
Run Code Online (Sandbox Code Playgroud)
<input id='file' type='file' accept='text/plain'><br>
<pre id='output'>...</pre>
Run Code Online (Sandbox Code Playgroud)