Solved : Create a copy of existing file on SD Card

I wanted to create a simple program to be able to copy an existing file on a SD card and write it to another file with a different name.

The code :

/*
  Example sketch to Copy an existing file on a SD card to another file with a different name(!) ...
  The circuit:
   SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK  - pin 13
 ** CS   - pin 4
*/

#include <SPI.h>
#include <SdFat.h>
SdFat sd;

SdFile myOrigFile;
SdFile myDestFile;

// Place holders for Source and Destination files..
char sourceFile[13] = "test.txt" ;
char destnFile[13] = "destn.txt" ;

const int chipSelect = 4;
int data;

void setup() {

  Serial.begin(9600);

  Serial.println("Input any character to start");
  while (Serial.read() <= 0) {}
  Serial.println();


  // Initialize SdFat and report error if any..

  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) {
    sd.initErrorHalt();
  }

  //================================================

  // Open two file references - one for soure and one for destination and copy.

  if (!sd.remove(destnFile)) {
    sd.errorHalt(" Error removing destination file");       // First delete any previous destinatiuon file..
  }

  if (!myOrigFile.open(sourceFile, FILE_READ)) {
    sd.errorHalt("opening source file for read failed");
  }

  if (!myDestFile.open(destnFile, FILE_WRITE)) {
    sd.errorHalt("opening destn file for write failed");
  }
  while ((data = myOrigFile.read()) >= 0) {
    myDestFile.write(myOrigFile.read());
  }
  myOrigFile.close();
  myDestFile.close();
  //=================================================

  // Open the source and destination file for verifying:

  if (!myOrigFile.open(sourceFile, FILE_READ)) {
    sd.errorHalt("opening source file for read failed");
  }
  Serial.println("test.txt:");

  // read from the file until there's nothing else in it:
  while ((data = myOrigFile.read()) >= 0) {
    Serial.write(data);
  }
  Serial.println();
  // close the file:
  myOrigFile.close();

  if (!myDestFile.open(destnFile, FILE_READ)) {
    sd.errorHalt("opening destn file for read failed");
  }
  Serial.println("destn.txt:");

  // read from the file until there's nothing else in it:
  while ((data = myDestFile.read()) >= 0) {
    Serial.write(data);
  }
  // close the file:
  myDestFile.close();

}

void loop() {
  // no code here..
}

//===============================================

But I wonder why the destination file has all Odd numbered characters missing? Look at the resulting Serial monitor screen shot that is attached...

Capture.PNG

You read two bytes and write one byte.

  while ((data = myOrigFile.read()) >= 0) {
    myDestFile.write(myOrigFile.read());
  }

Try this:

  while ((data = myOrigFile.read()) >= 0) {
    myDestFile.write(data);
  }

You could get more speed with something like this. You can use any size buffer.

  size_t n;  
  uint8_t buf[64];
  while ((n = myOrigFile.read(buf, sizeof(buf))) > 0) {
    myDestFile.write(buf, n);
  }

Thanks. It's clear now. Will check out the option with buffer to reduce time of copying.

Incidentally in an earlier thread regarding wiping SD cards you had mentioned about a native wear levelling that happens if they are formatted with the original tools. Does this also apply if I keep on using the sd.remove() method on only two files with fixed names over and over ?? ( a full wipe takes lot of time :wink:

Does this also apply if I keep on using the sd.remove() method on only two files with fixed names over and over ?? ( a full wipe takes lot of time :wink:

Remove will cause very little wear.

Thanks .

You have been a great help in sorting out issues with respect to the SD card ..

1 Like