flyingbin
flyingbin

Reputation: 1097

How to using javascript to read files into an array in order

I have a bunch of text files on server side with file names 0.txt, 1.txt, 2.txt, 3.txt and so forth. I want to read the content of all files and store them in an array A, such that A[0] has 0.txt's content, A[1] has 1.txt's, ...

How can I do it in Javascript / jquery?

Originally, I used $.ajax({}) in jQuery to load those text files. But it didn't work, because of the asynchronous nature of ajax. I tried to set $.ajax({...async=false...}), but it was very slow -- I have ~1000 10KB files to read in total.

Upvotes: 1

Views: 1680

Answers (3)

Mifeng
Mifeng

Reputation: 1565

from your question, you want to load txt file from server to local:

var done = 0, resultArr = [], numberOfFiles = 1000;

function getHandler(idx) {
    return function(data) {
        resultArr[idx] = data;
        done++;
        if (done === numberOfFiles) {
            // tell your other part all files are loaded
        }
    }
}

for (var i = 0; i < numberOfFiles; i++) {
    $.ajax(i + ".txt").done(getHandler(i));
}

jsFiddle: http://jsfiddle.net/LtQYF/1/

Upvotes: 1

Oleg
Oleg

Reputation: 24988

What you're looking for is File API introduced in HTML5 (working draft).

The examples in this article will point you in the right direction. Remember that the end user will have to initiate the action and manually select the files - otherwise it would have been a terrible idea privacy- and security-wise.

Update:

I found (yet again) the mozilla docos to be more readable! Quick html mockup:

<input type="file" id="files" name="files[]" onchange="loadTextFile();" multiple/>
<button id="test"onclick="test();">What have we read?</button>

...and the JavaScript:

var testArray = []; //your array

function loadTextFile() {
  //this would be tidier with jQuery, but whatever
  var _filesContainer = document.getElementById("files");
  //check how many files have been selected and iterate over them
  var _filesCount = _filesContainer.files.length;
  for (var i = 0; i < _filesCount; i++) {
    //create new FileReader instance; I have to read more into it
    //but I was unable to just recycle one
    var oFReader = new FileReader();

    //when the file has been "read" by the FileReader locally
    //log its contents and push them into an array
    oFReader.onload = function(oFREvent) {
      console.log(oFREvent.target.result);
      testArray.push(oFREvent.target.result);
    };

    //actually initiate the read
    oFReader.readAsText(_filesContainer.files[i]);
  }
}

//sanity check
function test() {
  for (var i = 0; i < testArray.length; i++) {
    console.warn(testArray[i]);
  }
}​

Fiddled

Upvotes: 1

jeff.vanvoorst
jeff.vanvoorst

Reputation: 119

You don't give much information to give a specific answer. However, it is my opinion that "it doesn't work because of the asynchronous nature of ajax" is not correct. You should be able to allocate an array of the correct size and use a callback for each file. You might try other options such as bundling the files on the server and unbundling them on the client, etc. The designs, that address the problem well, depend on specifics that you have not provided.

Upvotes: -1

Related Questions