file COPY on SD card

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
KLF
Posts: 37
Joined: Mon Jan 03, 2022 5:16 pm

file COPY on SD card

Post by KLF » Wed Apr 06, 2022 8:54 am

Good morning all,

I want to COPY (NOT move) a file on SD card from a working directory into an archive directory,
but I didn't find a copy command.
Maybe I searched in a wrong way, but I guess a file copy should be possible isn't it?

Thanky for any help
Klaus

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: file COPY on SD card

Post by Roberthh » Wed Apr 06, 2022 10:58 am

Where.did you expect a copy command. (Micro)Python is not a shell. You can easily create a copy command yourself. There is also a lib with sh like commands called upysh, which has a cp command for file copy.

KLF
Posts: 37
Joined: Mon Jan 03, 2022 5:16 pm

Re: file COPY on SD card

Post by KLF » Wed Apr 06, 2022 1:07 pm

Robert,

I thougt there is os.rename, os.remove, os.mkdir ... etc. available therefore also os.filecopy could be avalilable.

But I did as you suggested and coded the copy by myself (learned from the sh lib).
It works, but for bigger files it is to slow for me.
Therefore I changed to move the file by renaming it, which is much much faster.

Thanks a lot
Klaus

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: file COPY on SD card

Post by Roberthh » Wed Apr 06, 2022 1:12 pm

renaming works only within a file system, not across file systems.

KLF
Posts: 37
Joined: Mon Jan 03, 2022 5:16 pm

Re: file COPY on SD card

Post by KLF » Wed Apr 06, 2022 1:23 pm

Yes that is the case in my project.
I only want to move from one directory to another.

Nicolett
Posts: 7
Joined: Mon Apr 11, 2022 1:16 pm

Re: file COPY on SD card

Post by Nicolett » Thu Apr 14, 2022 7:39 am

So is there a way to copy a file from SD to another directory using one of the Python libs?

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: file COPY on SD card

Post by Roberthh » Thu Apr 14, 2022 8:26 am

yes: upysh in micropython-lib

KLF
Posts: 37
Joined: Mon Jan 03, 2022 5:16 pm

Re: file COPY on SD card

Post by KLF » Thu Apr 14, 2022 8:28 am

Nicolett,

here is my solution which I took from the lib upysh.
But a 1.5 Myte file takes time of nearly a minute, therefor I do a movement instead (takes time of a 1 second or less).

Best
Klaus

Code: Select all


def copyfile(srcf, destf):
    if srcf == destf:
        print("Destination file must be different than source")
        return
    try:
        st = os.stat(srcf)
    except:
        print("'{}' not found".format(srcf))
        return
    try:
        st = os.stat(destf)
        print("'{}' exists".format(destf))
        return
    except:
        pass
    try:
        fs = open(srcf, 'rb')
        try:
            fd = open(destf, 'wb')
        except:
            fs.close()
            print("Error opening '{}'".format(srcf))
            return
        try:
            print('3')
            while True:
                buf = fs.read(1024)
                if len(buf) == 0:
                    break
                else:
                    fd.write(buf)
            print('Fertig')
        except:
            try:
                fd.close()
                os.remove(destf)
            except:
                pass
            print("Error during copy")
        fd.close()
        fs.close()
    except:
        print("Error opening '{}'".format(srcf))
        
        

    
copyfile('/sd/DATALOG.csv', '/sd/Archiv/DATALOG123.csv')

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: file COPY on SD card

Post by Roberthh » Thu Apr 14, 2022 8:47 am

If you look at upysh.py, you'll see that the copy operation uses a preallocated buffer and memoryview. That avoids the allocation during copy and speeds up the transfer. If you have sufficient memory, you could set the buffer size to 4096. That is the FAT block size and helps copying speed as well. A modified cp command from upysh would then be:

Code: Select all

def cp(s, t):
    try:
        if os.stat(t)[0] & 0x4000:  # is directory
            t = t.rstrip("/") + "/" + s
    except OSError:
        pass
    buf = bytearray(4096)
    buf_mv = memoryview(buf)
    with open(s, "rb") as s, open(t, "wb") as t:
        while (n := s.readinto(buf)) > 0:
            t.write(buf_mv[:n])

Post Reply