Python-bestandsbewerkingen

Ik kreeg een fout "IOError: [Errno 0] Error" met dit python-programma:

from sys import argv
file = open("test.txt", "a+")
print file.tell() # not at the EOF place, why?
print file.read() # 1
file.write("Some stuff will be written to this file.") # 2
# there r some errs when both 1 & 2
print file.tell()
file.close()

wat is het probleem? Deze 2 onderstaande gevallen zijn goed:

from sys import argv
file = open("test.txt", "a+")
print file.tell() # not at the EOF place, why?
# print file.read() # 1
file.write("Some stuff will be written to this file.") # 2
# there r some errs when both 1 & 2
print file.tell()
file.close()

en:

from sys import argv
file = open("test.txt", "a+")
print file.tell() # not at the EOF place, why?
print file.read() # 1
# file.write("Some stuff will be written to this file.") # 2
# there r some errs when both 1 & 2
print file.tell()
file.close()

toch, waarom

print file.tell() # not at the EOF place, why?

drukt het formaat van het bestand niet af, is "a +" de toevoegmodus? dan zou de pointer naar EOF moeten wijzen?

ik gebruik Windows 7 en Python 2.7.

13
Weet je zeker dat text.txt bestaat?
toegevoegd de auteur Dhara, de bron
Zie mijn bijgewerkte antwoord, deze oplossing zou moeten werken. Ik heb het op hetzelfde platform + Python-versie geprobeerd als jij
toegevoegd de auteur Dhara, de bron
Kun je de versie van Python die je gebruikt en het besturingssysteem toevoegen?
toegevoegd de auteur Dhara, de bron
Waar haal je de fout vandaan? Het probleem lijkt te zijn dat je een bestand probeert te lezen dat in de toevoegmodus is geopend
toegevoegd de auteur Dhara, de bron
Je code werkt goed voor mij. tell retourneert 0 net na het openen van het bestand, natuurlijk, waarom zou je iets anders verwachten?
toegevoegd de auteur Lev Levitsky, de bron

2 antwoord

Python gebruikt de fopen-functie van stdio en geeft de modus door als argument. Ik ga ervan uit dat je vensters gebruikt, omdat @Lev zegt dat de code prima werkt op Linux.

Het volgende komt uit de fopen documentatie van vensters, dit kan een idee om uw probleem op te lossen:

Wanneer het toegangstype "r +", "w +" of "a +" is opgegeven, beide lezen   en schrijven zijn toegestaan ​​(het bestand is naar verluidt geopend voor "update").   Wanneer u echter overschakelt tussen lezen en schrijven, moet er een zijn   tussenkomende fflush, fsetpos, fseek of terugspoelen. De huidige   positie kan worden opgegeven voor de fsetpos- of fseek-bewerking, als   gewenst.

Dus de oplossing is om file.seek() toe te voegen vóór de file.write() aanroep. Gebruik file.seek (0, 2) om toe te voegen aan het einde van het bestand.

Voor uw referentie werkt file.seek als volgt:

Gebruik f.seek (offset, from_what) om de positie van het bestandsobject te wijzigen.   De positie wordt berekend door offset aan een referentiepunt toe te voegen; de   referentiepunt wordt geselecteerd door het from from who-argument. Een from_what   waarde van 0 meetwaarden vanaf het begin van het bestand, 1 gebruikt de stroom   bestandspositie en 2 gebruikt het einde van het bestand als referentiepunt.   from_wat kan worden weggelaten en staat standaard op 0, aan het begin van de   bestand als referentiepunt.

[reference: http://docs.python.org/tutorial/inputoutput.html]

Zoals vermeld door @lvc in de comments en @Burkhan in zijn antwoord, kun je de nieuwere open functie gebruiken van de io-module . Ik wil er echter op wijzen dat de write-functie in dit geval niet precies hetzelfde werkt - u moet unicode-reeksen als invoer opgeven [Gewoon prefix een u aan de reeks in uw geval]:

from io import open
fil = open('text.txt', 'a+')
fil.write('abc') # This fails
fil.write(u'abc') # This works

Gebruik ten slotte de naam 'bestand' niet als een variabelenaam, omdat deze verwijst naar een ingebouwd type en stil wordt overschreven, wat leidt tot enkele moeilijk te herkennen fouten.

10
toegevoegd
Kan dan een Windows-probleem zijn
toegevoegd de auteur Dhara, de bron
Ik gebruik vensters, Python 2.7, hoe zit het met jou?
toegevoegd de auteur Dhara, de bron
Jazeker, maar het lukt niet als het bestand wat tekst bevat
toegevoegd de auteur Dhara, de bron
@LevLevitsky, daar kon ik niet zeker van zijn in de documentatie, maar je hebt gelijk, de code werkt
toegevoegd de auteur Dhara, de bron
a + staat lezen toe.
toegevoegd de auteur Lev Levitsky, de bron
Bovendien opent het ook niet-bestaande bestanden zonder fouten.
toegevoegd de auteur Lev Levitsky, de bron
Dat doet het niet, althans niet op mijn systeem.
toegevoegd de auteur Lev Levitsky, de bron
Ubuntu Linux, Python 2.7
toegevoegd de auteur Lev Levitsky, de bron
Als dit een platformverschil is, is de gemakkelijkste oplossing: van io importeren openen . Dit gebruikt de nieuwe open van Py3, die zich overal hetzelfde gedraagt ​​zoals het draait.
toegevoegd de auteur lvc, de bron
@ user1477871 ja, van io import open werkt in Py2.7 - het vervangt de ingebouwde open functie met de nieuwere (die nu de standaard is).
toegevoegd de auteur lvc, de bron
Meer gegevens! Als ik vanuit de console onder vscode loop, krijg ik deze vervelende fout. Als ik in plaats daarvan ren van cmder (aka cmder.net ), werkt het prima. Voor de volledigheid werkt ook een vanilla cmd.exe. Dus er kan iets zijn over hoe vscode omgaat met ... I/O?
toegevoegd de auteur Mark Allen, de bron
@Dhara, zeker, bestand 'test.txt' bestaat.
toegevoegd de auteur imsrch, de bron
@Dhara ik heb het bericht bijgewerkt.
toegevoegd de auteur imsrch, de bron
@LevLevitsky ik heb het bericht bijgewerkt.
toegevoegd de auteur imsrch, de bron
@lvc Ik gebruik Python 2.7
toegevoegd de auteur imsrch, de bron

The solution is to use open from io

D:\>python
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('file.txt','a+')
>>> f.tell()
0L
>>> f.close()
>>> from io import open
>>> f = open('file.txt','a+')
>>> f.tell()
22L
6
toegevoegd