2016-11-02 7 views
1
open System 
//helpfunction 
let fileReplace filename needle replace = 
    let replaceIn (reader:System.IO.StreamReader) needle (replace: String) = 
    while not(reader.EndOfStream) do 
     let mutable allText = reader.ReadToEnd() 
     allText <- allText.Replace(needle, replace) 
    reader.Close() 

    //start 
    let reader = System.IO.File.OpenText filename 
    let newText = replaceIn reader needle replace 
    let writer = System.IO.File.CreateText filename 
    writer.Write newText ; writer.Close() 

// testing 
let filename = @".\abc.txt" 
let needle = "med" 
let replace = "MED" 
fileReplace filename needle replace 

나는 한 무리의 움직이는 reader.Close()를 실험했지만 결과는 아직 없다. 나는 을 reader.Close() 아래에 삽입하면 올바른 결과를 출력하므로 필자에게 그것이 잘못되었다는 것을 의심 할 때 의심된다. med를 abc.txt로 대체하는 코드가 필요합니다. 대신 빈 abc.txt를 남깁니다.F # - fileReplace, txt의 단어를 덮어 쓰지만 실행시 txt의 기존 내용을 덮어 쓴다.

답변

2

작성한 replaceIn 함수는 아무 것도하지 않습니다. 의이을 분리 보자

let replaceIn (reader:System.IO.StreamReader) needle (replace: string) = 
    while not(reader.EndOfStream) do 
     let mutable allText = reader.ReadToEnd() 
     allText <- allText.Replace(needle, replace) 
    reader.Close() 

첫째,이 기능의 유형을 보면 :

val replaceIn : reader:System.IO.StreamReader -> needle:string -> replace:string -> unit 

주의해야 할 첫 번째 것은이 함수가 항상 newText을 의미 ()의 값을 가지며, unit를 반환한다는 것입니다 , 파일 내용에 관계없이. 즉, 항상 파일에 아무 것도 쓰지 않습니다.

또한 루프가 불필요합니다. 스트림의 끝까지 읽었지만 스트림이 끝날 때까지 반복합니다.이 루프는 필요하지 않습니다. 결과를 저장하기 위해 생성하는 가변 변수가 루프 안에 있기 때문에 어쨌든 루프의 결과를 관찰 할 수있는 방법도 없습니다.


그래서, 대안을 살펴 보자 : 당신이 볼 수 있듯이

let fileReplace filename (needle : string) (replace : string) = 
    let allText = System.IO.File.ReadAllText filename 
    let newText = allText.Replace(needle, replace) 
    System.IO.File.WriteAllText(filename, newText) 

, 당신도 독자를 만들 필요가 없습니다, 당신은 System.IO.File 단지 도우미 기능을 할 수 있습니다.