@immobln: Naja, `fin` und `fout` sind als Namen jetzt auch nicht so wirklich schön.
@all: Etwas einfacher wäre es wenn man die `writelines()`-Methode verwendet:
Code: Alles auswählen
#!/usr/bin/env python3
def main():
with open("blubb.html", "r", encoding="utf-8") as lines:
with open("bla.html", "w", encoding="utf-8") as target_file:
target_file.writelines(lines)
if __name__ == "__main__":
main()
Da die Quelldatei gar nicht UTF-8 kodiert vorliegen muss, kann das zu Fehlern/Programmabbruch führen. Man muss aber auch gar nicht über die Textdarstellung gehen, sondern würde hier einfach die Datei als Binärdatei komplett einlesen und wieder schreiben können:
Code: Alles auswählen
#!/usr/bin/env python3
def main():
with open("blubb.html", "rb") as source_file:
with open("bla.html", "wb") as target_file:
target_file.write(source_file.read())
if __name__ == "__main__":
main()
Mit dem `pathlib`-Modul kann man sich das öffnen und schliessen sparen, weil `Path`-Objekte da praktische Methoden bieten:
Code: Alles auswählen
#!/usr/bin/env python3
from pathlib import Path
def main():
Path("bla.html").write_bytes(Path("blubb.html").read_bytes())
if __name__ == "__main__":
main()
Die beiden letzten Varianten haben den Nachteil, dass sie bei Dateien die (deutlich) kleiner als der Arbeitsspeicher sind, recht problemlos funktionieren, bei richtig grossen Dateien aber nicht. Deshalb kopiert man in der Regel Blöcke mit einer Grösse die bestimmt in den Arbeitsspeicher passen. Zum Beispiel in Blöcken von 64 KiB:
Code: Alles auswählen
#!/usr/bin/env python3
def main():
with open("blubb.html", "rb") as source_file:
with open("bla.html", "wb") as target_file:
chunks = iter(lambda: source_file.read(64 * 1024), b"")
target_file.writelines(chunks)
if __name__ == "__main__":
main()
Am einfachsten (und sicherer) ist es aber das schon erwähnte `shutil`-Modul zu verwenden, statt das Rad selbst neu zu erfinden:
Code: Alles auswählen
#!/usr/bin/env python3
import shutil
def main():
shutil.copy("blubb.html", "bla.html")
if __name__ == "__main__":
main()
Das ist auch gegebenenfalls effizienter, weil es unter bestimmten Umständen auf ausgewählten Betriebssystemen andere, effizientere Wege für das kopieren verwendet. Und es sichert über eine Ausnahme dagegen ab, das Quelle und Ziel die selbe Datei beschreiben. Dazu muss ja nicht zwingend der Name gleich sein, es gibt ja beispielsweise Dateisysteme mit harten Links wo verschiedene Pfade auf die physisch selbe Datei verweisen können. Das prüfen die ganzen anderen Varianten ja nicht.
@derda: `content` kommt beispielsweise als Attribut bei der `requests`-Bibliothek bei Serverantworten vor, wenn man das HTML (oder auch was anderes) per HTTP von einem Webserver holt. Ansonsten kann man den eingelesenen Inhalt einer Datei natürlich auch so nennen, wenn man den an einen sinnvollen Namen binden möchte.
Wenn man an HTML etwas ändern möchte, dann üblicherweise nicht am Text selbst, sondern mit Hilfe eines HTML-Parsers der die Struktur des Dokumentes erfasst. `BeautifulSoup` ist da recht beliebt. Dem Parser würde ich auch die Binärdaten aus der Datei übergeben und nicht den Text, denn wie gesagt, die Kodierung muss nicht die automagisch von Python ”geratene” sein, und HTML bietet die Möglichkeit die Kodierung in der Datei selbst anzugeben. Da kann sich ein HTML-Parser die Information her holen.