【问题标题】:How to read a local text file?如何读取本地文本文件?
【发布时间】:2013-01-04 23:14:48
【问题描述】:

我正在尝试编写一个简单的文本文件阅读器,方法是创建一个接收文件路径并将每行文本转换为 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();
}

这里出了什么问题?

previous revision 稍微更改代码后,这似乎仍然不起作用,现在它给了我一个 XMLHttpRequest 异常 101。

我已经在 Firefox 上对此进行了测试,它可以正常工作,但在 Google Chrome 中它无法正常工作,并且它一直给我一个异常 101。我怎样才能让它不仅可以在 Firefox 上工作,而且可以在其他浏览器上工作(尤其是 Chrome)?

【问题讨论】:

  • 具体发生了什么。数组中没有任何内容吗?还是只是“错误”的东西..?
  • 你是在本地机器上测试吗?确保测试status0 以及200
  • @JeffreySweeney 是的,我正在本地机器上测试它。我已将文本文件存储在与 javascripts 和 html 相同的位置

标签: javascript file-io xmlhttprequest


【解决方案1】:

您需要检查状态 0(当使用 XMLHttpRequest 在本地加载文件时,您不会收到返回的状态,因为它不是来自 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);
}

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

readTextFile("file:///C:/your/path/to/file.txt");

【讨论】:

  • 我实际上是在 Mac 上处理这个问题,所以我还要指定文​​件://??
  • 尝试将file:///User/Danny/Desktop/javascriptWork/testing.txt 放在浏览器的网址栏中,看看是否可以看到文件..
  • 它不需要是绝对路径。这对我来说很好用:readTextFile('Properties/version.txt');谢谢!
  • 由于我们是从网络服务器读取数据,我们应该将异步设置为true。如果这是一个简单的 local 搜索,那么将 async 设置为 false 是可以的,但 onreadystatechange 在设置为 false 时不需要。这是文档:w3schools.com/ajax/ajax_xmlhttprequest_send.asp
  • 这在 Chrome 中不起作用(可能是其他浏览器)你会得到“跨源请求仅支持协议方案:http、data、chrome、chrome-extension、https、chrome-extension-资源。”
【解决方案2】:

在javascript中引入fetch api后,读取文件内容再简单不过了。

读取文本文件

fetch('file.txt')
  .then(response => response.text())
  .then(text => console.log(text))
  // outputs the content of the text file

读取 json 文件

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

2018 年 7 月 30 日更新(免责声明):

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

Update-2(免责声明):

出于与 Chrome 相同的(安全)原因,此技术不适用于版本 68(2019 年 7 月 9 日)以上的 FirefoxCORS request not HTTP。见https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp

【讨论】:

  • 太棒了!引用 Fetch 标准:“提供一致的处理:URL 方案、重定向、跨域语义、CSP、服务工作者、混合内容、Referer”。我想这意味着告别优秀的 ol'FileReaders 和 HttpRequests(我不会错过它们;)
  • 但是如何使用 text 并将其放入字符串变量中以便在其他地方使用? (无论我对它做什么,我都会不断得到“未定义”。)
  • @not2qubit 获取文本文件是异步操作。您正在变得未定义,因为您在完全读取文件之前使用了变量。您必须在 Promise 回调中使用它或使用类似 javascript “async await” 运算符之类的东西。
  • Fetch API cannot load file:///C:/Users/path/to/file/file.txt. URL scheme must be "http" or "https" for CORS request.
【解决方案3】:

访问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>

【讨论】:

  • 链接很好,但您应该“始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。”见How do I write a good answer
  • 此示例处理用户输入的文本文件,但我认为问题是关于服务器本地的文件。
  • @S.Kirby 正如 OP 在回答有关它是在本地运行还是在远程服务器上运行的问题时所说:it's all local. all in one folder nothing else.。此外,其他人(比如我)可能对如何在本地进行操作有疑问。
【解决方案4】:

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);
  }   
});
<input type="file" id="myFile">
<hr>
<textarea style="width:500px;height: 400px" id="output"></textarea>

【讨论】:

  • 我不确定这是否能回答这个 4 岁的问题。 OP 没有上传文档,他们试图从路径中读取同一目录中的文本文件。如果你要回答这么老的问题,至少要写一个简短的摘要,说明为什么你认为你的答案现在比其他人更好,或者自问题以来语言发生了怎样的变化,以保证新的答案。
  • 使用我自己现有的文件上传输入 html - 复制从 var reader = new FileReader();reader.readAsBinaryString(..) 的行 - 它读取我的文本文件的内容。干净,优雅,像魅力一样工作。对我来说这个线程的最佳答案 - 谢谢!
【解决方案5】:

是的,JS 可以读取本地文件(参见 FileReader()),但不能自动读取:用户必须使用 html &lt;input type="file"&gt; 将文件或文件列表传递给脚本。

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

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

要让JS自动访问本地fs,需要创建的不是html文件,里面有JS,而是hta文档。

一个hta文件里面可以包含JS或者VBS。

但 hta 可执行文件只能在 Windows 系统上运行。

这是标准的浏览器行为。

Google Chrome 也使用 fs API,更多信息在这里:http://www.html5rocks.com/en/tutorials/file/filesystem/

【讨论】:

    【解决方案6】:

    现代解决方案:

    如下使用fileOrBlob.text()

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

    当用户通过该输入上传文本文件时,它将被记录到控制台。 Here's a working jsbin demo.

    这是一个更详细的版本:

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

    目前(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>
    

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

    【讨论】:

    • 什么是路径根?
    • 您需要在示例中创建 Blob,否则我认为这对人们没有用处。
    【解决方案7】:

    使用Fetch 和异步函数

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

    【讨论】:

    • 我得到“对于 CORS 请求,URL 方案必须是“http”或“https”。'
    • 完美解决方案。很简单,就是“logFileText('./test.txt')”
    【解决方案8】:

    尝试创建两个函数:

    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]);
    }
    

    【讨论】:

    • 这适用于哪些浏览器(似乎有 6 人尝试过 :-))
    【解决方案9】:

    证明你已经尝试过了,输入“false”如下:

     rawFile.open("GET", file, false);
    

    【讨论】:

      【解决方案10】:

      其他示例 - 我的具有 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>
      

      【讨论】:

      • 文件返回base64输出
      【解决方案11】:

      这可能会有所帮助,

          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();
      

      【讨论】:

        【解决方案12】:

        由于同源策略,不支持 Chrome 中的本地 AJAX 调用。

        chrome 上的错误信息是这样的: “协议方案不支持跨源请求:http、data、chrome、chrome-extension、https。”

        这意味着 chrome 会为每个域创建一个虚拟磁盘,以保存该域使用 http/https 协议提供的文件。对该虚拟磁盘之外的文件的任何访问都受到同源策略的限制。 AJAX 请求和响应发生在 http/https 上,因此不适用于本地文件。

        Firefox 没有这样的限制,因此您的代码可以在 Firefox 上正常运行。但是也有适用于 chrome 的解决方法:see here

        【讨论】:

        • 您的“查看此处”链接已损坏。
        【解决方案13】:

        除了上面的一些答案,这个修改后的解决方案对我有用。

        <input id="file-upload-input" type="file" class="form-control" accept="*" />
        

        ....

        let fileInput  = document.getElementById('file-upload-input');
        let files = fileInput.files;
        
        //Use createObjectURL, this should address any CORS issues.
        let filePath = URL.createObjectURL(files[0]);
        

        ....

        function readTextFile(filePath){
            var rawFile = new XMLHttpRequest();
            rawFile.open("GET", filePath , true);
            rawFile.send(null);
        
            rawFile.onreadystatechange = function (){
                if(rawFile.readyState === 4){
                    if(rawFile.status === 200 || rawFile.status == 0){
                        var allText = rawFile.responseText;
                        console.log(allText);
                    }
                }
            }     
        }
        

        【讨论】:

          【解决方案14】:
          function readTextFile(file) {
              var rawFile = new XMLHttpRequest(); // XMLHttpRequest (often abbreviated as XHR) is a browser object accessible in JavaScript that provides data in XML, JSON, but also HTML format, or even a simple text using HTTP requests.
              rawFile.open("GET", file, false); // open with method GET the file with the link file ,  false (synchronous)
              rawFile.onreadystatechange = function ()
              {
                  if(rawFile.readyState === 4) // readyState = 4: request finished and response is ready
                  {
                      if(rawFile.status === 200) // status 200: "OK"
                      {
                          var allText = rawFile.responseText; //  Returns the response data as a string
                          console.log(allText); // display text on the console
                      }
                  }
              }
              rawFile.send(null); //Sends the request to the server Used for GET requests with param null
          }
          
          readTextFile("text.txt"); //<= Call function ===== don't need "file:///..." just the path 
          

          - 从 javascript 读取文件文本
          - 使用 javascript 从文件中的控制台日志文本
          - Google chrome 和 mozilla firefox

          就我而言,我有这种文件结构:

          console.log 结果:

          【讨论】:

          • 以下是错误显示:从源 'null' 访问 XMLHttpRequest 在 'file:///C:/{myLocalPath}PropertiesFile.txt' 已被 CORS 策略阻止:交叉原始请求仅支持协议方案:http、data、chrome、chrome-extension、https。
          【解决方案15】:
          <html>
          <head>
              <title></title>
              <meta charset="utf-8" />
              <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
              <script type="text/javascript">
                  $(document).ready(function () {            
                          $.ajax({`enter code here`
                              url: "TextFile.txt",
                              dataType: "text",
                              success: function (data) {                 
                                      var text = $('#newCheckText').val();
                                      var str = data;
                                      var str_array = str.split('\n');
                                      for (var i = 0; i < str_array.length; i++) {
                                          // Trim the excess whitespace.
                                          str_array[i] = str_array[i].replace(/^\s*/, "").replace(/\s*$/, "");
                                          // Add additional code here, such as:
                                          alert(str_array[i]);
                                          $('#checkboxes').append('<input type="checkbox"  class="checkBoxClass" /> ' + str_array[i] + '<br />');
                                      }
                              }                   
                          });
                          $("#ckbCheckAll").click(function () {
                              $(".checkBoxClass").prop('checked', $(this).prop('checked'));
                          });
                  });
              </script>
          </head>
          <body>
              <div id="checkboxes">
                  <input type="checkbox" id="ckbCheckAll" class="checkBoxClass"/> Select All<br />        
              </div>
          </body>
          </html>
          

          【讨论】:

            【解决方案16】:

            在js(data.js)加载中获取本地文件数据:

            function loadMyFile(){
                console.log("ut:"+unixTimeSec());
                loadScript("data.js?"+unixTimeSec(), loadParse);
            }
            function loadParse(){
                var mA_=mSdata.split("\n");
                console.log(mA_.length);
            }
            function loadScript(url, callback){
            
                var script = document.createElement("script")
                script.type = "text/javascript";
            
                if (script.readyState){  //IE
                    script.onreadystatechange = function(){
                        if (script.readyState == "loaded" ||
                                script.readyState == "complete"){
                            script.onreadystatechange = null;
                            callback();
                        }
                    };
                } else {  //Others
                    script.onload = function(){
                        callback();
                    };
                }
            
                script.src = url;
                document.getElementsByTagName("head")[0].appendChild(script);
            }
            function hereDoc(f) {
              return f.toString().
                  replace(/^[^\/]+\/\*![^\r\n]*[\r\n]*/, "").
                  replace(/[\r\n][^\r\n]*\*\/[^\/]+$/, "");
            }
            function unixTimeSec(){
                return Math.round( (new Date()).getTime()/1000);
            }
            

            data.js 文件如:

            var mSdata = hereDoc(function() {/*!
            17,399
            1237,399
            BLAHBLAH
            BLAHBLAH
            155,82
            194,376
            */});
            

            动态 unixTime queryString 防止缓存。

            AJ 在 web http:// 中工作。

            【讨论】:

            【解决方案17】:

            如果要提示用户选择文件,则读取其内容:

            // read the contents of a file input
            const readInputFile = (inputElement, callback) => {
              const reader = new FileReader();
              reader.onload = () => {
                callback(reader.result)
              };
              reader.readAsText(inputElement.files[0]);
            };
            // create a file input and destroy it after reading it
            export const openFile = (callback) => {
              var el = document.createElement('input');
              el.setAttribute('type', 'file');
              el.style.display = 'none';
              document.body.appendChild(el);
              el.onchange = () => {readInputFile(el, (data) => {
                callback(data)
                document.body.removeChild(el);
              })}
              el.click();
            }
            

            用法:

            // prompt the user to select a file and read it
            openFile(data => {
                console.log(data)
              })
            

            【讨论】:

              【解决方案18】:

              您可以导入我的库:

              &lt;script src="https://www.editeyusercontent.com/preview/1c_hhRGD3bhwOtWwfBD8QofW9rD3T1kbe/code.js?pe=yikuansun2015@gmail.com"&gt;&lt;/script&gt;

              然后,函数fetchfile(path)将返回上传的文件

              <script src="https://www.editeyusercontent.com/preview/1c_hhRGD3bhwOtWwfBD8QofW9rD3T1kbe/code.js"></script>
              <script>console.log(fetchfile("file.txt"))</script>

              请注意:如果 HTML 代码是本地的,在谷歌浏览器上会出现错误,但在线保存 HTML 代码和文件然后运行在线 HTML 文件可以。

              【讨论】:

                【解决方案19】:

                为了使用 chrome 通过JavaScript 读取本地文件文本,chrome 浏览器应使用参数--allow-file-access-from-files 运行以允许 JavaScript 访问本地文件,然后您可以使用 XmlHttpRequest 读取它,如下所示:

                var xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = function () {
                   if (xmlhttp.readyState == 4) {
                       var allText = xmlhttp.responseText;          
                            }
                        };
                xmlhttp.open("GET", file, false);
                xmlhttp.send(null);
                

                【讨论】:

                  【解决方案20】:

                  如何读取本地文件?

                  通过使用这个,您将通过 loadText() 加载文件,然后 JS 将异步等待文件被读取并加载,之后它将执行 readText() 函数允许您继续正常的 JS 逻辑(您也可以编写loadText() 函数上的 try catch 块,以防出现任何错误),但对于本例,我将其保持在最低限度。

                  async function loadText(url) {
                      text = await fetch(url);
                      //awaits for text.text() prop 
                      //and then sends it to readText()
                      readText(await text.text());
                  }
                  
                  function readText(text){
                      //here you can continue with your JS normal logic
                      console.log(text);
                  }
                  
                  loadText('test.txt');
                  

                  【讨论】:

                  • 你好像有function-itis的案例
                  【解决方案21】:

                  我知道,我在这个聚会上迟到了。让我告诉你我有什么。

                  这是一个简单的文本文件阅读

                  var path = "C:\\path\\filename.txt"
                  var fs = require('fs')
                  fs.readFile(path , 'utf8', function(err, data) {
                    if (err) throw err;
                    console.log('OK: ' + filename);
                    console.log(data)
                  });
                  

                  我希望这会有所帮助。

                  【讨论】:

                  • 您应该引用文件路径。此外,他的代码使用了 DOM 库,这意味着他的意思是 vanilla JavaScript,而不是 node.js。
                  【解决方案22】:

                  此函数用于浏览器和打开文件选择器对话框,并在用户选择后将文件读取为二进制文件并使用读取数据调用回调函数:

                  function pickAndReadFile(callback) {
                      var el = document.createElement('input');
                      el.setAttribute('type', 'file');
                      el.style.display = 'none';
                      document.body.appendChild(el);
                      el.onchange = function (){
                          const reader = new FileReader();
                          reader.onload = function () {
                              callback(reader.result);
                              document.body.removeChild(el);
                          };
                          reader.readAsBinaryString(el.files[0]);
                      }
                      el.click();
                  }
                  

                  并像这样使用它:

                  pickAndReadFile(data => {
                    console.log(data)
                  })
                  

                  【讨论】:

                  • 你不应该再使用 readAsBinaryString...
                  猜你喜欢
                  • 1970-01-01
                  • 2012-02-17
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-06-13
                  • 2015-03-27
                  相关资源
                  最近更新 更多