2016-04-16 10 views
1

den folgenden Code vor:Unregelmäßige (scheinbar zufällig) Verhalten von seek() und split() in Python

import sys 
with open(sys.argv[1]) as data_file: 
    data_file.readline() #skipping lines of texts 
    data_file.readline() 
    data_file.readline() #skipping lines of texts 
    data_file.readline() 
    data_file.readline() #skipping lines of texts 
    data_file.readline() #skipping lines of texts 
    data_file.readline() #skipping lines of texts 
    data_file.readline() #skipping lines of texts 
    data_file.readline() #skipping lines of texts 
    while True: 
     print "#" 
     pos=data_file.tell() 
     next_mol=data_file.readline().split() 
     print next_mol 
     data_file.seek(pos) 
     print data_file.readline().split() 

hier sys.argv [1] ist der Name der Textdatei, die die folgenden Daten enthält :

ITEM: TIMESTEP 
31500000 
ITEM: NUMBER OF ATOMS 
28244 
ITEM: BOX BOUNDS pp pp pp 
0.706774 63.6072 
1.77317 62.6918 
-4.27518 67.4572 
ITEM: ATOMS id type x y z 
1 1 8.07271 20.6394 38.953 
2 1 7.45444 20.2706 37.5682 
3 1 7.94593 21.3438 36.5822 
4 2 8.88701 22.2414 37.422 
5 6 8.97587 21.7898 38.6976 
6 7 9.51512 23.1098 36.8675 
7 1 9.83459 22.2787 39.7728 
8 3 8.54346 19.7726 39.3733 
9 3 7.3188 20.9572 39.6053 
10 3 6.33686 20.2798 37.6457 
11 3 7.62824 19.2464 37.1935 
12 3 7.14438 21.9616 36.2781 
13 3 8.4454 20.9589 35.6742 
14 3 9.51704 23.2023 40.2712 
15 3 10.839 22.4705 39.342 
16 3 9.84061 21.5031 40.5668 

gibt mir folgende Ausgabe:

# 
['1', '1', '8.07271', '20.6394', '38.953'] 
['71', '20.6394', '38.953'] 
# 
['2', '1', '7.45444', '20.2706', '37.5682'] 
['1', '7.45444', '20.2706', '37.5682'] 
# 
['3', '1', '7.94593', '21.3438', '36.5822'] 
['1', '7.94593', '21.3438', '36.5822'] 
# 
['4', '2', '8.88701', '22.2414', '37.422'] 
['2', '8.88701', '22.2414', '37.422'] 
# 
['5', '6', '8.97587', '21.7898', '38.6976'] 
['6', '8.97587', '21.7898', '38.6976'] 
# 
['6', '7', '9.51512', '23.1098', '36.8675'] 
['7', '9.51512', '23.1098', '36.8675'] 
# 
['7', '1', '9.83459', '22.2787', '39.7728'] 
['1', '9.83459', '22.2787', '39.7728'] 
# 
['8', '3', '8.54346', '19.7726', '39.3733'] 
['3', '8.54346', '19.7726', '39.3733'] 
# 
['9', '3', '7.3188', '20.9572', '39.6053'] 
['3', '7.3188', '20.9572', '39.6053'] 
# 
['10', '3', '6.33686', '20.2798', '37.6457'] 
['0', '3', '6.33686', '20.2798', '37.6457'] 

ich beide Saiten zwischen '#' erwarten gleich zu sein. Fehle ich hier etwas?

+0

'file.readline()' verwendet fast sicher einen Puffer; Die Dateiposition wird nach dem zuletzt erzeugten Zeilenumbruch nicht richtig angezeigt. Sie wird nach dem Read-Ahead-Puffer verwendet, um neue Zeilen zu finden. –

+0

irgendwelche besseren Alternativen? oder Alternativen zum Lesen der nächsten Zeile und zum Zurückkehren zu vorherigen Positionen? – ipcamit

+0

Warum willst du das machen? Warum nicht einfach nur bereits gelesene Zeilen speichern? –

Antwort

2

file.readline() verwendet einen Read-Ahead-Puffer Zeilenumbrüche zu finden, so kann es Ihnen eine saubere Linie zurück, die in \n endet. Die Alternative besteht darin, Byte für Byte zu lesen, bis eine neue Zeile gefunden wird, was äußerst ineffizient wäre.

Als solche liest Ihre erste file.readline() ein Stück Informationen aus der Datei ein, analysiert die erste Zeile und gibt diese zurück. Dann wird ein nächster Aufruf von file.readline() kann gut sein, können Ihnen die nächste Zeile aus dem Puffer allein geben usw.

Durch die Zeit, die Sie Ihre while Schleife erhalten, der Read-Ahead-Puffer mit jedem Dinge gefüllt wurde 1 1 8.072 (die ersten Bytes nach der ITEM: ATOMS id type x y z Zeile). Der nächste file.readline() Aufruf liest dann in mehr Puffer eine andere Newline zu finden, die in der nächsten Zeile der Datei Position nach dem ersten 2 bewegen, usw.

Sie können nicht zuverlässig die richtige Datei Position aus einer Datei und erhalten Verwenden Sie file.readline() Anrufe; Sie müssen die Anzahl der gelesenen Zeilen, die tatsächliche Puffergröße und den Stil der in der Datei verwendeten Zeilentrennzeichen berücksichtigen. Ihr Problem kann fast sicher auf verschiedene Arten gelöst werden, wie das Speichern der bereits gelesenen Zeilen in einer Warteschlange oder einem Stapel einer Art, die in späteren Wiederholungen Ihrer Schleife verwendet werden.