Saturday, 9 December 2017

Python read text file as binary alternativ


7. Input och Output Det finns flera sätt att presentera utmatningen av ett program. Data kan skrivas ut i en läsbar form eller skrivas till en fil för framtida bruk. I det här kapitlet diskuteras några av möjligheterna. 7,1. Avancerad utmatningsformatering Hittills har we8217ve stött på två sätt att skriva värden: uttalanden och utskriftsdeklarationen. (En tredje metod använder filen write () för filobjekt. Standardutdatafilen kan refereras till som sys. stdout. Se biblioteksreferensen för mer information om detta.) Ofta you8217ll vill ha mer kontroll över formateringen av din produktion än helt enkelt utskriftsutrymme separerade värden. Det finns två sätt att formatera din produktion. Det första sättet är att göra all strängen som hanterar dig själv med hjälp av snedskärning och sammanbindningsoperationer. Du kan skapa vilken layout du kan tänka dig. Strängtyperna har några metoder som utför användbara operationer för vadderingssträngar till en viss kolumnbredd, vilka kommer att diskuteras inom kort. Det andra sättet är att använda metoden str. format (). Strängmodulen innehåller en Mall-klass som erbjuder ännu ett sätt att ersätta värden i strängar. En fråga kvarstår förstås: hur konverterar du värden till strängar Lyckligtvis har Python sätt att konvertera valfritt värde till en sträng: skicka det till repr () eller str () funktionerna. Funktionen str () är avsedd att återge representationer av värden som är ganska mänskliga läsbara, medan repr () är avsedd att generera representationer som kan tolkas av tolken (eller kommer att tvinga en SyntaxError om det inte finns någon motsvarande syntax). För objekt som don8217t har en särskild representation för konsumtion kommer str () att returnera samma värde som repr (). Många värden, såsom tal eller strukturer som listor och ordböcker, har samma representation med hjälp av endera funktionen. Strängar och flytpunkter har i synnerhet två olika representationer. Här är två sätt att skriva ett bord med rutor och kuber: (Observera att i det första exemplet fanns ett mellanslag mellan varje kolumn med det sätt som skrivet fungerar: det lägger alltid till mellanrum mellan dess argument.) Detta exempel visar str. rjust () - metoden för strängobjekt, som högerjusterar en sträng i ett fält med en viss bredd genom att fylla den med mellanslag till vänster. Det finns liknande metoder str. ljust () och str. center (). Dessa metoder skriver inte någonting, de returnerar bara en ny sträng. Om inmatningssträngen är för lång kan de inte styra den, men returnera den oförändrad. Detta kommer att förstöra din kolonnlayout, men det är oftast bättre än alternativet, vilket skulle ligga om ett värde. (Om du verkligen vill ha trunkning kan du alltid lägga till en skivoperation, som i x. ljust (n): n.) Det finns en annan metod, str. zfill (). som lägger en numerisk sträng till vänster med nollor. Det förstår om plus - och minustecken: Grundläggande användning av metoden str. format () ser så här ut: parenteserna och tecknen i dem (kallade formatfält) ersätts med objekten som passerade in i metoden str. format (). Ett tal i parentes hänvisar till positionen för objektet som passerat i metoden str. format (). Om nyckelordsargument används i metoden str. format (), hänvisas deras värden med namnet på argumentet. Positions - och nyckelordsargument kan kombineras godtyckligt: ​​7.2. Läsa och skriva filer öppna () returnerar ett filobjekt, och brukar användas med två argument: öppna (filnamn, läge). Det första argumentet är en sträng som innehåller filnamnet. Det andra argumentet är en annan sträng som innehåller några tecken som beskriver hur filen ska användas. läge kan r vara när filen bara kommer att läsas, w för att bara skriva (en befintlig fil med samma namn kommer raderas) och en öppnar filen för att lägga till eventuella data som är skriven till filen läggs automatiskt till i slutet. r öppnar filen för både läsning och skrivning. Modusargumentet är valfritt r antas om it8217s utelämnas. På Windows, b bifogas läget öppnar filen i binärt läge, så det finns också lägen som rb. wb. och rb. Python på Windows skiljer mellan text och binära filer Ändra karaktären i textfiler ändras automatiskt lite när data läses eller skrivs. Denna modifiering av bakom kulisserna till fildata är bra för ASCII-textfiler, men it8217ll korrumperar binära data som i JPEG - eller EXE-filer. Var försiktig med att använda binärt läge när du läser och skriver sådana filer. På Unix gör det inte ont för att lägga till ett b i läget, så du kan använda den plattformen - oberoende av alla binära filer. 7.2.1. Metoder för filobjekt Resten av exemplen i det här avsnittet förutsätter att ett filobjekt som heter f redan har skapats. För att läsa en fil8217s innehåll, ring f. read (storlek). som läser en viss mängd data och returnerar den som en sträng. Storlek är ett valfritt numeriskt argument. När storleken är utelämnad eller negativ läses hela innehållet i filen och returneras it8217s ditt problem om filen är dubbelt så stor som ditt machine8217s minne. Annars läses och returneras högst storleksbyte. Om slutet av filen har nåtts kommer f. read () att returnera en tom sträng (kvot). f. readline () läser en enda rad från filen en nylinje tecken (n) lämnas i slutet av strängen och lämnas endast i den sista raden av filen om filen doesn8217t slutar i en ny linje. Detta gör returvärdet entydigt om f. readline () returnerar en tom sträng, slutet på filen har nåtts, medan en tom linje representeras av n. en sträng som bara innehåller en enda ny linje. För att läsa linjer från en fil kan du slingra över filobjektet. Detta är minneseffektivt, snabbt och leder till enkel kod: Om du vill läsa alla rader i en fil i en lista kan du också använda listan (f) eller f. readlines (). f. write (string) skriver innehållet i strängen till filen, returnerar None. För att skriva något annat än en sträng måste det först konverteras till en sträng: f. tell () returnerar ett heltal som ger filen object8217s nuvarande position i filen, mätt i byte från början av filen. För att ändra filen object8217s position, använd f. seek (offset, fromwhat). Positionen beräknas från att man lägger till förskjutning till en referenspunkt, varvid referenspunkten väljs av det från vilket argument. Ett från vilket värde av 0 åtgärder från början av filen, 1 använder nuvarande filposition och 2 använder slutet av filen som referenspunkt. fromwhat kan utelämnas och standardinställningar till 0, med början av filen som referenspunkt. När du är klar med en fil, ring f. close () för att stänga den och frigöra eventuella systemresurser som tagits upp av den öppna filen. Efter att ha ringt f. close (). försök att använda filobjektet kommer automatiskt att misslyckas. Det är bra att använda det med nyckelordet när man hanterar filobjekt. Detta har fördelen att filen är ordentligt stängd efter avslutad svit, även om ett undantag höjdes på vägen. Det är också mycket kortare än att skriva motsvarande försök - äntligen block: Filobjekt har några ytterligare metoder, som isatty () och truncate () som används mindre ofta, kolla Bibliotekshänvisning för en komplett guide till filobjekt. 7.2.2. Att spara strukturerad data med json Strings kan enkelt skrivas till och läsas från en fil. Numren tar lite mer ansträngning, eftersom read () - metoden bara returnerar strängar, vilket måste överföras till en funktion som int (). som tar en sträng som 123 och returnerar sitt numeriska värde 123. När du vill spara mer komplexa datatyper som nestade listor och ordböcker blir parsing och serialisering för hand komplicerad. I stället för att användarna ständigt skriver och debuggerar kod för att spara komplicerade datatyper till filer, tillåter Python dig att använda det populära datautbytesformatet JSON (JavaScript Object Notation). Standardmodulen kallad json kan ta Python datahierarkier och konvertera dem till strängpresentationer kallas serialiseringen. Rekonstruering av data från strängrepresentationen kallas deserialiserande. Mellan serialisering och deserialisering kan strängen som representerar objektet ha lagrats i en fil eller data, eller skickas över en nätverksanslutning till en avlägsen maskin. JSON-formatet används vanligtvis av moderna applikationer för att möjliggöra datautbyte. Många programmerare är redan bekanta med det, vilket gör det till ett bra val för driftskompatibilitet. Om du har ett objekt x. Du kan visa sin JSON-strängrepresentation med en enkel kodkod: En annan variant av dumpfunktionen (), kallad dump (). serialiserar bara objektet till en fil. Så om f är ett filobjekt öppet för skrivning kan vi göra det här: Att avkoda objektet igen, om f är ett filobjekt som har öppnats för läsning: Denna enkla serialiseringsteknik kan hantera listor och ordböcker, men serialiserar godtyckliga klassförekomster i JSON kräver lite extra ansträngning. Referensen för json-modulen innehåller en förklaring till detta. pickle - pickle-modulen i motsats till JSON. pickle är ett protokoll som tillåter serialisering av godtyckligt komplexa Python-objekt. Som sådan är det specifikt för Python och kan inte användas för att kommunicera med applikationer skrivna på andra språk. Det är också osäkert som standard: deserialiserande pickle-data som kommer från en otillförlitlig källa kan exekvera godtycklig kod om data skapades av en skicklig angripare. Med förslag på chrispy: Observera att det med uttalandet inte är tillgängligt i versioner av Python under 2,5. För att använda det i v 2.5 måste du importera det: I 2.6 behövs det inte. I Python 3 är det lite annorlunda. Vi kommer inte längre få raka tecken från strömmen i byte-läge utan byteobjekt, så vi behöver ändra tillståndet: Eller som Benhoyt säger, hoppa över det inte lika och dra nytta av det faktum att b utvärderar till falskt. Detta gör koden kompatibel mellan 2.6 och 3.x utan några ändringar. Det skulle också rädda dig från att ändra villkoret om du går från byteläge till text eller omvänd. För att läsa en fil en byte åt gången (ignorerar bufferten) kan du använda den inbyggda funktionen med två argument iter (callable, sentinel): Det kallar file. read (1) tills det returnerar inget b (tom bytestring). Minnet växer inte obegränsat för stora filer. Du kan passera buffering0 för att öppna (). för att inaktivera bufferten garanterar det att endast en byte läses per iteration. med - information stänger filen automatiskt, inklusive fallet när koden nedan ger upphov till ett undantag. Trots närvaron av intern buffert som standard är det fortfarande ineffektivt att bearbeta en byte åt gången. Till exempel, här är blackhole. py-verktyget som äter allt det ges: 1,5 GBs med standardbuffert på min maskin och bara 7,5 MB om bufsize1. Det vill säga det är 200 gånger långsammare att läsa en byte åt gången. Ta hänsyn till om du kan skriva om din behandling för att använda mer än en byte åt gången och om du behöver prestanda. mmap låter dig behandla en fil som en biträde och ett filobjekt samtidigt. Det kan fungera som ett alternativ för att ladda hela filen i minnet om du behöver åtkomst till båda gränssnitt. I synnerhet kan du iterera en byte åt gången över en minneskortad fil bara med en vanlig för-loop: mmap stöder skivanotation. Till exempel returnerar mmi: ilen len bytes från filen som börjar vid position i. Kontexthanteringsprotokollet stöds inte före Python 3.2. Du måste kalla mm. close () uttryckligen i det här fallet. Iterating över varje byte med mmap förbrukar mer minne än file. read (1). men mmap är en storleksordning snabbare. svarat den 16 november kl 13:47. Sammanfattningsvis är alla de briljanta punkterna Chrispy, Skurmedel, Ben Hoyt och Peter Hansen det bästa alternativet för att bearbeta en binär fil en byte i taget. För pythonversioner 2.6 och senare, eftersom: pythonbuffertar internt - ingen anledning att läsa bitar DRY-principen - repetera inte läsrad med uttalande säkerställer att en ren fil nära byte utvärderar till falskt när det inte finns fler byte (inte när en byte är noll) Eller använd JF Sebastians lösning för förbättrad hastighet Eller om du vill ha det som en generatorfunktion som demonstreras av codeape: svarat 6 sep 13 kl 7:55 JFSebastian - du är 100 korrekt - förmodligen mycket snabbare ndash Holger Bille 9 maj 16 kl 8:12 Som det länkade svaret säger att behandlingen av en byte åt gången är långsam i Python även om läsningarna är buffrade. Prestanda kan förbättras drastiskt om flera byte i taget kan behandlas som i exemplet i det länkade svaret: 1,5 GB vs 7,5 MB. ndash J. F. Sebastian maj 9 16 kl. 11:49 Om du har mycket binär data att läsa kanske du vill överväga struct-modulen. Det är dokumenterat som att konvertera mellan C och Python typer, men naturligtvis är byte bitgrupper, och om de skapades som C-typer spelar ingen roll. Om din binära data innehåller två tvåbyte heltal och ett 4-byte heltal kan du exempelvis läsa dem enligt följande (exempel taget från strukturdokumentation): Du kan hitta det här mer bekvämt, snabbare eller båda än att uttryckligen slingra över innehållet i en fil svarade den 1 juli kl. 11:24 Läs binärfil i Python och loopa över varje byte. Låt oss skapa en fil: Nu kan vi iterera över det, med hjälp av rb-flaggan (läsläge, byte-läge). Observera att multipeln för slingor inte ökar komplexiteten (som förblir O (n)) - det här är bara hur du slår ljuvligt över en fil - linje för rad. Detta kommer att slingra över varje byte i koden, utan någon hacky. read (1) verksamhet. Det här är mycket mer pythoniskt och naturligt än det ögonblickliga och komplicerade jag har sett i de andra svaren här. Buffrad läsning Om du har stora filer utan nya linjer kanske du vill buffra din läsning. Python 2.7 kräver io. open att få det här: Och vi har nu en buffradläsare: Python 3s inbyggd öppen funktion är 2s io. open. Hur läser och skriver filer i Python När du programmerar i Python-språket bortom de mest triviala programmen, you39ll är vanligtvis skyldig att läsa data från och skriva data till filer som existerar utanför själva programmet. Python ger enkla mekanismer för att komma åt och ändra specifika filer med hjälp av standardfunktioner som ingår i kärnspråket. Öppna filer i Python Bestäm om användarpolicy. Du behöver veta om du behöver läsa från eller skriva till filen innan du kan öppna filen. Öppna bara filen med de behörigheter du verkligen behöver och öppna inte en fil i läs - och skrivläge när du bara behöver läsa av det. Detta kommer att förhindra oavsiktligt att skriva till filen du inte borde skriva till. Bestäm om du ska använda ASCII eller binärt läge. Om du läser text, vill du använda ASCII-läget. Om du läser binär data, använd binärt läge. I det här läget översätts linjens ändringar till det läge som operativsystemet använder. Skapa lägessträngen. Den första tecknen är läs - eller skrivläge. Om du vill öppna i binärt läge, lägg till en quotbquot till slutet av strängen. Till exempel, för att läsa i ASCII-läget, skulle lägessträngen vara quotrquot och för att skriva i binärt läge skulle modesträngen vara quotwbquot. Öppna filen med hjälp av den öppna funktionen. Spara det resulterande filobjektet i en variabel. Till exempel: f öppen (quotfilenamegoesherequot, quotrquot) Läs från filer i Python Iterate över alla linjer. Ett filobjekt kan användas som en samling med quotforquot-loopen. Du kan iterera över alla rader i en fil (en gemensam åtgärd) med förklaringen. för rad i f: print line Sök till en viss punkt i filen. Filer läses inte alltid i följd så det är ofta nödvändigt att söka till en viss punkt i filen innan den läses från filen. Du kan göra detta med sökmetoden för ett filobjekt. Sök till 100: e byte f. seek (100) Sök till 10 byte från nuvarande byte f. seek (10, 1) Läs binära data från en fil. Med hjälp av läsmetoden för ett filobjekt kan du läsa ett godtyckligt antal byte från en fil. Läs 16 byte från filen buf f. read (16) Skriv till Python-filer Skriv data till en fil. Om en fil öppnas i skrivläge kan du skriva ASCII eller binära data till den. Detta görs med skrivmetoden för ett filobjekt. f. write (quotThis är lite textquot) Skriv objekt till en fil. Om du behöver spara ett objektets interna tillstånd kan du citera det. För att plocka upp ett föremål måste du först importera pickle-modulen. Därefter kan du hämta nästan alla föremål med pickle. dump-funktionen. importera pickle pickle. dump (anyobject, f) Stäng filen. När skrivningen är klar måste du stänga filen. Detta säkerställer att alla buffertar är spolade och filen inte är låst så att andra program kan komma åt det. Detta görs med det närmaste metoden för ett filobjekt.

No comments:

Post a Comment