ezieragabriel / arduino

Automatically exported from code.google.com/p/arduino
Other
0 stars 0 forks source link

openNextFile does not correctly list files in use #904

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Method A:
1. Open the root of an SD card
root = SD.open("/");
2. List the files with the example code 
printDirectory(root,0);
2A. All files on card show up.
3. Open a (different) file variable for writing 
SD.open("datafile.csv",FILE_WRITE);
4. List the files with the example code 
printDirectory(root,0);
5. File opened for writing does not show up from now till reset.

Method B:
1. Open the root of an SD card
root = SD.open("/");
2. Open a (different) file variable for writing 
SD.open("datafile.csv",FILE_WRITE);
3. List the files with the example code 
printDirectory(root,0);
4. File opened for writing does not show up from now till reset.

What version of the Arduino software are you using? On what operating
system?  Which Arduino board are you using?
Arduino 1.0
Windows 7 x64 Ultimate
Arduino Uno SMD + Ethernet Shield R3
Kingston 1GB MicroSD Card in Ethernet Shield

Please provide any additional information below.
Sample code and sample output attached.

Original issue reported on code.google.com by Srin...@gmail.com on 29 Apr 2012 at 11:57

Attachments:

GoogleCodeExporter commented 9 years ago
Does it show up again if you close the file first?

Original comment by dmel...@gmail.com on 9 May 2012 at 12:36

GoogleCodeExporter commented 9 years ago
Resolved - if you rewind the directory before you list it.

This sample code was based off the "listfiles" example that came with the 
Arduino 1.0 environment.  (In the 
arduino-1.0-windows\arduino-1.0\libraries\SD\examples\listfiles folder, (aka 
Examples -> SD -> listfiles in the GUI).)
I have attached an updated listfiles.ino that corrects the reported issue.

*new*
I still think there is a bug in the file index code.  
When I open the root "File" (directory) the first time after boot, then the 
File is opened at the beginning as expected and documented.  However, after 
running through the file's contents (listing the directory), the file index 
pointer seems stuck in its last position, even if you close() and open() the 
file.
Sample code and output included.

NOTES (NOT using the rewind 'fix'):
First Time Through: All files listed correctly.
<closed root, re-opened>
Second Time Through: the root file did not list non-directory contents.  (the 
root File maintained an index pointing to the end of the file??)
Third Time Through: No output listed at all.  (either the root File, or all 
File's maintained an index pointing to the end of the file??)
<close root, re-opened>
Fourth Time Through: See Second Time Through.

Original comment by Srin...@gmail.com on 9 May 2012 at 2:33

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Srinity, do you have a fix we could apply to the library?  For example, would 
something like calling rewind from within open() or close() do the trick?

Original comment by dmel...@gmail.com on 30 May 2012 at 1:56

GoogleCodeExporter commented 9 years ago
I think this is a duplicate of: 
http://code.google.com/p/arduino/issues/detail?id=832
which has a known solution. Essentially the example is flawed in that it 
doesn't close file handles and runs out. (there are by necessity a limited 
number)

Original comment by kevin.os...@gmail.com on 30 May 2012 at 3:10

GoogleCodeExporter commented 9 years ago
Srinity, do you think Kevin's right, that this is just a problem of not closing 
the files?

Original comment by dmel...@gmail.com on 1 Jun 2012 at 3:14

GoogleCodeExporter commented 9 years ago
I think its both issues.  The example is most def. flawed, and comment #3 
included a substitute example (listfile.ino) that has both rewind() and close() 
- without both items, the list code doesn't work repeatedly.

My thought is that the rewind() function should be included in the open() 
function, iff mode == FILE_READ.  Pros:  Opening a file / directory to read it 
always starts it at the beginning, which should adhere to the API documentation 
as written on the website.

Original comment by Srin...@gmail.com on 2 Jun 2012 at 1:35

GoogleCodeExporter commented 9 years ago
Cool.  Have you tried adding the rewind() to open()?  Do you have a patch or 
modified file you can share that's been tested?

Original comment by dmel...@gmail.com on 2 Jun 2012 at 3:13

GoogleCodeExporter commented 9 years ago
Ok,

Downloaded the latest 1.0.1 Arduino release for Windows.  Created a Mercurial 
repo using the "arduino-1.0.1" folder as the base.

I made one change to SD.cpp (added a manual file seek to position 0), and 
updated the listfiles.ino example code.

I tested this code against the openNextFile_Bug.ino posted in comment 3, and 
everything now appears to be working as expected.

I tried creating a patch file, which is attached.  Also attached are the two 
changed files, in case the patch doesn't work.

Original comment by Srin...@gmail.com on 4 Jun 2012 at 1:56

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks!  I'll try this out and commit it when I've got a board in front of me.

Original comment by dmel...@gmail.com on 4 Jun 2012 at 12:19

GoogleCodeExporter commented 9 years ago
When I tried this out, it seems like adding the "dir.rewindDirectory();" to 
printDirectory() fixed the problem, regardless of whether or not the 
"file.seekSet(0);" was in SD.cpp.  Should we instead patch SD.cpp to do the 
rewind() if the file is a directory?  Do you want to make a patch for that?

Original comment by dmel...@gmail.com on 5 Jun 2012 at 3:13

GoogleCodeExporter commented 9 years ago
I believe that file.seekSet(0) was added for both files and directories.  
(Files seemed to open at the last location if opened for read only a second 
time.)

Original comment by Srin...@gmail.com on 29 Jun 2012 at 1:19

GoogleCodeExporter commented 9 years ago
The resolution is simple and does not require any modifications to SD.cpp.
Simply add entry.close() to the example code as shown below.

Gary

void printDirectory(File dir, int numTabs) {
    while(true) {

     File entry =  dir.openNextFile();
      if (! entry) {
        // no more files
        // return to the first file in the directory
        dir.rewindDirectory();
        break;
      }
      for (uint8_t i=0; i<numTabs; i++) {
        Serial.print('\t');
      }
      Serial.print(entry.name());
      if (entry.isDirectory()) {
        Serial.println("/");
        printDirectory(entry, numTabs+1);
      } else {
        // files have sizes, directories do not
        Serial.print("\t\t");
        Serial.println(entry.size(), DEC);
      }
      entry.close();
    }
 }

Original comment by garygfle...@hotmail.com on 30 Oct 2012 at 8:47