Python Forum
How to save files in a separate directory
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to save files in a separate directory
#1
Hey, i'm working on a games save/loading function.
this is my code that find the file path for the players save (loading the save)
it works by finding where the file is being run from, then replacing the program with the playerdata subfolder so it can find the save files.

 absolutepath = os.path.abspath(__file__)
      filename = os.path.basename(absolutepath)
      dirname = absolutepath.replace(filename, "playerdata")
      filename = dirname + "\\username.txt"
      file = open(filename, 'r')
      player = file.read()
      file.close()
      absolutepath = os.path.abspath(__file__)
      filename = os.path.basename(absolutepath)
      dirname = absolutepath.replace(filename, "playerdata")
      filename = dirname + "\\coins.txt"
      file = open(filename, 'r')
      coins = file.read()
      file.close()
how can I use this system to save the file?
this is an example of code I would use to save files if they were in the same directory as the program.

                os.remove('username.txt')
                file = open('username.txt', 'a+')
                file.write(player)
                file.close()
                os.remove('coins.txt')
                file = open('coins.txt', 'a+')
                coins = str(coins)
                file.write(coins)
                file.close()


TL;DR it deletes the text files and replaces them with a new save - but as the files are in a subfolder it cannot locate them - how do i get it to save to a certain directory?
Reply
#2
Do you need a subfolder, or are you only using a subfolder because you have multiple files? I would save username and coins to a single file. In the code below I write both username and coins to the same file. And to cover all bases the file is in a subfolder of the module folder.
import pathlib

username = "Guido"
coins = 1000000

save_file = "save_files/data.txt"  # data save file relative path
with open(pathlib.Path(__file__).parent / save_file, "w") as file:
    file.write(f"{username}\n{coins}")

username = None
coins = None

with open(pathlib.Path(__file__).parent / save_file, "r") as file:
    username, coins = map(str.strip, file.readlines())
coins = int(coins) + 1
print(username, coins)
__file__ is the file name and path of the module currently running. pathlib.Path(__file__).parent strips off the filename. pathlib.Path(__file__).parent / save_file appends the subfolder and scores filename to the path.

I open the file for writing ("w" resets the file to empty) and write the username and coins separated by a linefeed. The resulting file looks like this:
Output:
Guido 1000000
To read the file back in I just do pretty much the same thing, but opening the file for reading "r" and read the lines. Because the file contains a linefeed after Guido, username has a linefeed at the end that we need to strip. Coins will be read in as a str and needs to be converted back to an int.

It is awkward that I have to strip the linefeed from the username and convert the coins to an int. This method wouldn't scale well to multiple users and multiple coins either. Maybe username and coins in your example are just that, examples, and in your real application you have a file full of usernames that map to a file full of coins. In that case I would still use a single file, but a different kind of file:

To save coins for multiple players you could use a CSV file.
import pathlib
import csv

players = {
   "Guido":1000000,
   "Dean":1,
   "Scordomaniac": 100
}

save_file = "save_files/data.csv"

print("Initial players", players)
with open(pathlib.Path(__file__).parent / save_file, "w", newline="") as file:
    writer = csv.writer(file)
    for player in players.items():
        writer.writerow(player)

players = {}
print("Before load", players)

with open(pathlib.Path(__file__).parent / save_file, "r") as file:
    reader = csv.reader(file)
    for player, coins in reader:
        players[player] = int(coins)
players["Guido"] += 1
print("After load", players)
This produces a file that looks like this:
Output:
Guido,1000000 Dean,1 Scordomaniac,100
And when I run my program I see that it accurately restores the player's scores.
Output:
Initial players {'Guido': 1000000, 'Dean': 1, 'Scordomaniac': 100} Before load {} After load {'Guido': 1000001, 'Dean': 1, 'Scordomaniac': 100}
It's nice that I don't have to strip the linefeeds, and the file is easy to read with player names and scores on the same line. But I still have to convert coins back to a string.

There are file types that save the data type information and restore the type automatically. My favorite of these is JSON because the files are relatively short and human readable when compared to something like a CSV.
import pathlib
import json

players = {
   "Guido":1000000,
   "Dean":1,
   "Scordomaniac": 100
}

save_file = "save_files/data.json"

print("Initial players", players)
with open(pathlib.Path(__file__).parent / save_file, "w") as file:
    json.dump(players, file)

players = None
print("Before load", players)

with open(pathlib.Path(__file__).parent / save_file, "r") as file:
    players = json.load(file)
players["Guido"] += 1
print("After load", players)
This produces a file that looks like this:
{"Guido": 1000000, "Dean": 1, "Scordomaniac": 100}
And when I run the program I see the player's scores are restored.
Output:
Initial players {'Guido': 1000000, 'Dean': 1, 'Scordomaniac': 100} Before load None After load {'Guido': 1000001, 'Dean': 1, 'Scordomaniac': 100}
Always tip Guido.
Scordomaniac likes this post
Reply
#3
i've tried using the json code you sent but i get this error:
Error:
Traceback (most recent call last): File "O:\Jackpot Studios\PyMemer BETA\saving.py", line 13, in <module> with open(pathlib.Path(__file__).parent / playerdata, "w") as file: TypeError: invalid file: WindowsPath('O:/Jackpot Studios/PyMemer BETA/playerdata/data.json')
how can this be fixed? all the files exist...
Reply
#4
Which version of Python are you using? Try this perhaps
with (pathlib.Path(__file__).parent / 'playerdata' / 'data.json').open("w") as file:
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Read directory listing of files and parse out the highest number? cubangt 5 331 Sep-28-2022, 10:15 PM
Last Post: Larz60+
  importing functions from a separate python file in a separate directory Scordomaniac 3 634 May-17-2022, 07:49 AM
Last Post: Pedroski55
  Separate text files and convert into csv marfer 6 1,385 Dec-10-2021, 12:09 PM
Last Post: marfer
  Rename Multiple files in directory to remove special characters nyawadasi 9 3,795 Feb-16-2021, 09:49 PM
Last Post: BashBedlam
  List of error codes to find (and count) in all files in a directory tester_V 8 2,391 Dec-11-2020, 07:07 PM
Last Post: tester_V
  How to merge all the files in a directory in to one file sutra 3 1,757 Dec-10-2020, 12:09 AM
Last Post: sutra
  Merging all file_name.log's files from directory to one and search “PerformanceINFO" sutra 0 1,230 Dec-09-2020, 05:14 PM
Last Post: sutra
  Copy files from subfolders into same name of subfolders at other directory rathoreanil 1 1,622 Oct-12-2020, 01:30 AM
Last Post: Larz60+
  Moving Files From Subdirectories To Another Directory Harshil 5 2,499 Oct-06-2020, 10:52 AM
Last Post: ndc85430
  Put all files in a directory into list. How? Denial 2 1,377 Sep-18-2020, 10:05 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020