2015-01-14 4 views
4

전체 파일을 메모리에로드하지 않고 한 줄씩 텍스트 파일을 읽으려는 경우 Rebol에서이 작업을 수행하는 일반적인 방법은 무엇입니까?Rebol에서 한 줄씩 텍스트 파일을 읽는 관용적 인 방법은 무엇입니까?

나는 다음을 수행하고,하지만 난 그것을 먼저 메모리에 전체 파일을로드하도록 (내가 틀렸다면 정정 해줘) 생각 :

foreach line read/lines %file.txt [ print line ] 

답변

5

적어도 Rebol2와

read/lines/direct/part %file.txt 1 

그러나 모든 줄을 한 줄씩 다른 줄로 표시하려면

과 같아야합니다.
f: open/lines/direct %test.txt 
while [l: copy/part f 1] [print l] 

이론적으로 당신은 원주민조차도 모든 기능을 대신 할 수 있습니다. 나는 아마 세트 새로운 foreach는

foreach_: :foreach 
foreach: func [ 
    "Evaluates a block for each value(s) in a series or a file for each line." 
    'word [get-word! word! block!] {Word or block of words to set each time (will be local)} 
    data [series! file! port!] "The series to traverse" 
    body [block!] "Block to evaluate each time" 
    /local port line 
] [ 
    either any [port? data file? data] [ 
     attempt [ 
      port: open/direct/lines data 
      while [line: copy/part port 1] [ 
       set :word line 
       do :body 
       line 
      ] 
     ] 
     attempt [close port] 
    ] [ 
     foreach_ :word :data :body 
    ] 
] 

에게 제공하기 위해 노력할 것입니다 : 워드 라인을 부분과 시도는 더 이름 충돌을 방지하고 의미있는 오류를 얻기 위해 정교해야한다.

+0

하지만'개방/라인/메모리에 전체 파일을로드 direct'합니까? 그게 내 질문에 따라 피하려고하는거야. – mydoghasworms

+1

아니요, '열기 만하면됩니다. 파일을 엽니 다. '읽는 동안 그것을 읽습니다. 음, 아마도 '일부 모드에서는 bufferst를 열어 놓을 수도 있지만 활용할 수있는 탐색 모드가 있습니다. - http://www.rebol.com/article/0199.html – pekr

+2

개인적인 경험에 비추어 볼 때, 그 열림/직선/직접 오픈/라인보다 적은 메모리를 사용할 수 있습니다. 그러나 더 큰 파일을 열면 차이점 만 보입니다. 아마도 최소한의 내부 버퍼가 사용되어 항상 항상 채워질 것입니다. – sqlab

2

open은가는 길입니다. 그러나 처럼 sqlab은 필요에 따라 달라집니다. /lines & /direct 상세 검색은 Rebol 3 open (아직)에 없습니다.

하지만 좋은 소식

file: open %movie.mpg 
while [not empty? data: read/part file 32000] [ 
    ; 
    ; read in 32000 bytes from file at a time 
    ; process data 
] 
close file 

그래서 그냥 버퍼에이 문제를 마무리 한 번에 한 줄을 처리 할 필요가 ... 당신은 여전히 ​​이러한 개선없이 REBOL 3 open to read in large files를 사용할 수 있다는 것입니다.

는 여기에 함께 넣어 한 원유 작업 예제 :

file: open/read %file.txt 
eol: newline 
buffer-size: 1000 
buffer: "" 
lines: [] 

while [ 
    ;; start buffering 
    if empty? lines [ 
     ;; fill buffer until we have eol or EOF 
     until [ 
      append buffer to-string data: read/part file buffer-size 
      any [ 
       empty? data 
       find buffer eol 
      ] 
     ] 
     lines: split buffer eol 
     buffer: take/last lines 
    ] 

    line: take lines 
    not all [empty? data empty? buffer] 
    ][ 
    ;; line processing goes here! 
    print line 
] 

close file 
+0

꽤 많은 코드입니다. 나는 Ruby에서 다음과 같은 것을하기를 바랐다.'open ('file.txt'). each {| line | 줄을 넣는다.''. 나는 파일이나 포트를 받아들이는 비슷한 일을하기 위해 Rebol에서'foreach' 함수의 변종을 쓸 수 있다고 생각합니다. 달리 표준 함수의 동작을 변경할 수 있습니까? 예를 들어 'foreach'가 '항구'를 받아 들일 수 있도록 하시겠습니까? – mydoghasworms

관련 문제