(in Sd Card) can i copy the entire file and rename it ?

i’m working with sd card and i want to copy the the entire file and rename it,
is this possible ?
i already ried to open the 2 files (one in reading and the second writing) but il takes alot of times reading byte/byte
thank you
:slight_smile:

i'm working with sd card and i want to copy the the entire file and rename it, is this possible ?

Do you want to copy a file or rename a file? They are two different operations.

but il takes alot of times reading byte/byte

So, use a big(ger) array, and read/write several bytes at a time.

i want to copy all the file,and after that to rename it

So open the existing file for reading, open a new one with your new name for writing and read from the one & write to the other. As noted above, you can do it char by char or use a larger buffer to speed things up.

This scenario gives you two copies of the file with appropriate names - no need to do a rename.

i did all what you told,except the long buffer,i didn't undrstand how to use it ?? i'm using directly while(...) {File.write(File1.Read())

thank you for the replay

i did all what you told,except the long buffer,i didn't undrstand how to use it ?? i'm using directly while(...) {File.write(File1.Read())

Well, I rather doubt that, as the method is read(), not Read().

Anyway, look at the documentation for the read() method. Depend on which (unspecified) library you are using, the read() method typically has several overloads. One, the one that you are using, takes no arguments and returns one character. Other versions take more arguments, and allow you to read more than one character at a time. Of course, you need to call that method, and then call the method to write() the data, as two separate actions, not with one embedded in the other.

I attached an example I did to an Arduino Mega 2560 + sd shield. :slight_smile:

You must save a file into the SDcard (default name “flor1.jpg”).

#include <SPI.h>
#include <SD.h>

char* file_name1 = “flor1.jpg”;
char* file_name2 = “flor2.jpg”;
byte ibuffer[3000];
int ibufferspace = sizeof(ibuffer);
File File1;
File File2;

void setup() {
Serial.begin(19200);
Serial.print(“Initializing SD card…”);
pinMode(53, OUTPUT);

if (!SD.begin(53)) {
Serial.println(“Initialization failed!”);
return;
}else {
Serial.println(“Initialization done.”);
}

File1 = SD.open(file_name1);
if (File1) {
Serial.println(“Opening the file: " + String(file_name1) + " done.”);
}else {
Serial.println("Error opening " + String(file_name1));
}

if(SD.exists(file_name2)) {
SD.remove(file_name2);
Serial.println(“File :” + String(file_name2) + " deleted…");
}

unsigned int previoustime = millis();
if (File1) {
File2 = SD.open(file_name2, FILE_WRITE);
if(File2) {
int i=0;
while (File1.available()>0) {
ibuffer = File1.read();

  • i++;*
  • if (i==ibufferspace) {*
  • File2.write(ibuffer,ibufferspace);*
  • i=0;*
  • }*
  • }*
  • File2.write(ibuffer,i-1);*
  • }*
  • Serial.println(“Done copying…”);*
  • File1.close();*
  • File2.close();*
  • }*
  • Serial.println(“Time: " + String((millis()-previoustime)/1000) + " seg”);*
    }
    void loop()
    {
  • // nothing happens after setup*
    }
    [/quote]

When I tried to compile,I got this error:

_0_0_0_sd-sd.ino: In function 'void setup()': _0_0_0_sd-sd:41: error: incompatible types in assignment of 'int' to 'byte [3000] {aka unsigned char [3000]}' incompatible types in assignment of 'int' to 'byte [3000] {aka unsigned char [3000]}'

??

When I tried to compile,I got this error:

When I try to compile, it works perfectly.

Of course, I am not compiling the same code as you are, since I haven't a clue what your code looks like.

Posting code in code tags makes you look smarter than posting code in quote tags, because code in code tags is not mangled by the forum software.

I thought it would waste space to repeat it, but… sigh

 #include <SPI.h>
#include <SD.h>

char* file_name1 = "flor1.jpg";
char* file_name2 = "flor2.jpg";
byte ibuffer[3000];
int ibufferspace = sizeof(ibuffer);
File File1;
File File2;

void setup() {
 Serial.begin(19200);
 Serial.print("Initializing SD card...");
 pinMode(53, OUTPUT);
 
 if (!SD.begin(53)) {
   Serial.println("Initialization failed!");
   return;
 }else {
   Serial.println("Initialization done.");
 }

 File1 = SD.open(file_name1);
 if (File1) {
   Serial.println("Opening the file: " + String(file_name1) + " done.");
 }else {
   Serial.println("Error opening " + String(file_name1));
 }

 if(SD.exists(file_name2)) {
   SD.remove(file_name2);
   Serial.println("File :" + String(file_name2) + " deleted...");
 }

 unsigned int previoustime = millis();
 if (File1) {
   File2 = SD.open(file_name2, FILE_WRITE);
   if(File2) {
     int i=0;
     while (File1.available()>0) {
       ibuffer = File1.read();
       i++;
       if (i==ibufferspace) {
         File2.write(ibuffer,ibufferspace);
         i=0;
       }
     }
     File2.write(ibuffer,i-1);
   }
   Serial.println("Done copying...");
   File1.close();
   File2.close();
 }
 Serial.println("Time: " + String((millis()-previoustime)/1000) + " seg");
}

void loop()
{
 // nothing happens after setup
}

I compiled for a Mega 256 with Arduino IDE 1.6.5 and got the error message above.

   Serial.println("Opening the file: " + String(file_name1) + " done.");

Pissing away resources on the String class to save having to use three Serial.print() calls is the height of laziness.

       ibuffer = File1.read();

The read() method that takes no arguments returns ONE character. You can NOT assign one character to an entire array. There is another version of the read() method that takes two arguments - an array to store data in and a number that defines the amount of data to read. RTFM.

jurs: but do read bigger buffers of bytes, i.e. - read buffer of 64 bytes - write buffer of 64 bytes In case the file size is not a multiple of 64, the last read/write operation will be less than 64 bytes.

Whether your file copy is slow or fast, is just a matter of clever coding.

Yeah, but to find what you need seems to be a 'mission impossible'. It goes something like this:

  • Go to the SD library reference.
  • Find something related to reading files; e.g. read.
  • Hmm, no example; that sucks.
  • Hmm, no mentioning of a read function / method that takes one or more arguments.
  • Go back to SD library reference.
  • Check the Read/Write example
  • Stupid example that I already based my code on.
  • Back to read.
  • Hmm, it says something about 'read() inherits from the Stream utility class'.
  • Lets see what we they say there.
  • Ah, there is a readBytesfunction / method. Maybe that will do the trick.

That way I came to the below (partial) code based on OP's code; I don't know if it works because I don't have an SD shield but I suspect it does.

  if (File1) {
    File2 = SD.open(file_name2, FILE_WRITE);
    if (File2) {
      while (File1.available() > 0)
      {
        int i = File1.readBytes(ibuffer, 64);
        File2.write(ibuffer, i);
      }
      // done, close the destination file
      File2.close();
    }
    Serial.println("Done copying...");
    // done, close the source file
    File1.close();
  }

In the three months that I have been using an Arduino I have never been impressed with the reference.

Why I survive the reference system is that I know what should be possible (based on previous experience in e.g. C (notC+++) under DOS and Linux) and hence what to search for (e.g. using google).

Why can the Serial reference provide a link to Serial.readBytes but the SD library reference can't.

I hope for OP that the above code works but no guarantee.

The FatFile.h file in the utility folder defines the actual File class. It contains the no-argument read method:

  int read() {
    uint8_t b;
    return read(&b, 1) == 1 ? b : -1;
  }

which, as you can see, actually calls the two argument method. So, off to find the two argument method. Well, hey, its the next function:

  /** Read data from a file starting at the current position.
   *
   * \param[out] buf Pointer to the location that will receive the data.
   *
   * \param[in] nbyte Maximum number of bytes to read.
   *
   * \return For success read() returns the number of bytes read.
   * A value less than \a nbyte, including zero, will be returned
   * if end of file is reached.
   * If an error occurs, read() returns -1.  Possible errors include
   * read() called before a file has been opened, corrupt file system
   * or an I/O error occurred.
   */
  int read(void* buf, size_t nbyte);

Why rely on the documentation when you have the source code?

Hmm sounds like me telling my boss 'here is the software you requested with the source code and you can yourself figure out how to configure it' :D

Anyway, if one needs to dig through the source code of the libraries, why provide documentation in the first place? To give the beginner the feeling that programming the Arduino is only for the Gods and not for the cattle, I assume?

'quod licet Jovi, non licet bovi' ;)

Anyway, if one needs to dig through the source code of the libraries, why provide documentation in the first place?

Because doing so is a good thing. Relying on it isn't.

PaulS, Without burdening anyone else - or you - with my problems - mostly a function of my 15% competence - is it reasonable to expect to be able to read an SD file on one arduino and via a 9600 bps serial connection copy it to an SD file on a second arduino? even if the transport requires SoftwareSerial?

if this should be possible, I'll just keep banging on it until i get it to work.

is it reasonable to expect to be able to read an SD file on one arduino and via a 9600 bps serial connection copy it to an SD file on a second arduino?

Yes.

Why such a slow baud rate?

Why do you need to copy data from one SD card to another that way?

PaulS: Yes.

Why such a slow baud rate?

Why do you need to copy data from one SD card to another that way?

I need to make it work at all, first, then I can boost speed to whatever will give me error-free copies.

The sending sd is on a teensy powered datalogger buried within an airframe where it isn't easy to get at between flights. the idea was to plug a nano powered box into a port on the outside of the plane and order the teensy to send the file to the nano-box.

if the softwareserial is where I'm having the trouble I'll use another teensy 3.2. to get another serial port.

My experience has been that I never make a single mistake with these things, almost always both hardware and software, but I'm patient and can usually substitute simple routines and other hardware and utlimately make something work, but the 15% comprehension can really slow me down.

Edit 3/1/16 OOPS: that should be that i seldom make a single mistake, usually it's several.

Hi Paul,
below is the sender code installed on a Teensy 3.2. The TSD refers to an SD module modified to quarter speed, so that the SD reader will run reliably with a Teensy running at 96 mHz.

the receiver code runs on a Nano.

I was unable to get reliable transmission above 9600 bps. Maybe the problem is in the code, because if I’m just sending the data to a terminal it looks ok.

??
Receiver code:

 /*
 * This seems to work ok 3-1-16 jaf
 */

#define I2C_ADDRESS 0x3C

#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

File dataFile;

SSD1306AsciiAvrI2c oled;

SoftwareSerial ss(4, 3);

void setup() {
  ss.begin(9600);
  Serial.begin(96s00);
  Serial.print("this is the startup");
 
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
  oled.setFont(System5x7);
  oled.clear();
  oled.println("record to SD-2");
  oled.println();

 Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    oled.println("initialization failed!");
    return;
  }
  oled.println("initialization done.");
  Serial.println("Initialization done");

  // so you have to close this one before opening another.
  dataFile = SD.open("planeSD.txt", FILE_WRITE);
  
  Serial.println("this is starting"); 
  delay(1000);
}
void loop() {
  dataFile.flush();
  while (ss.available() > 0) {
  char inChar = ss.read();
  dataFile.print(inChar);
  }

}

Sender Code:

 /*
 * Simple Dumpfile on Plane
2-28-16 jaf
Changed SD.h to TSD.h to agree with teensy library change
2-29-16 jaf
minor ajustments & change data-rate 3-1-16 jaf
 */

#include <TSD.h>
#include <SPI.h>

const int chipSelect = 10;

File dataFile;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial3.begin(9600);
  Serial.print("Initializing SD card...");
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  
   File dataFile = SD.open("altimu1.txt");
     dataFile.flush();
// if the file is available, read it:
  if (dataFile) {
    while (dataFile.available()) {
      char inbyte = dataFile.read();
      Serial3.print(inbyte);  
    }
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening altimu1.txt");
  }
 }

void loop()
{ 
}

see anything bizarre in here?

john

jferg: I need to make it work at all, first, then I can boost speed to whatever will give me error-free copies.

The sending sd is on a teensy powered datalogger buried within an airframe where it isn't easy to get at between flights. the idea was to plug a nano powered box into a port on the outside of the plane and order the teensy to send the file to the nano-box.

if the softwareserial is where I'm having the trouble I'll use another teensy 3.2. to get another serial port.

My experience has been that I never make a single mistake with these things, almost always both hardware and software, but I'm patient and can usually substitute simple routines and other hardware and utlimately make something work, but the 15% comprehension can really slow me down.

Edit 3/1/16 OOPS: that should be that i seldom make a single mistake, usually it's several.

Your experience includes going down the wrong path and calling it good?

You are reading serial data from an external device and having trouble writing that to a file on SD? Do you know that the SD library takes the bytes you 'write' to SD into the buffer (default 512 bytes) before actually sending them to the SD card?

You read the file at 9600 baud? Hey, found your actual bottleneck! Have you any idea how long bytes take to arrive at 9600 baud and what all else the controller can do in that time?