我被分配了一个编写程序的任务:
打开文件。
阅读内容。
用另一个单词替换特定单词。
将更改保存到文件中。
我确信我的代码可以打开,阅读和替换单词。当我添加“将更改保存到文件” - 部分时,会出现此问题。这是代码:
open System.IO
//Getting the filename, needle and replace-word.
System.Console.WriteLine "What is the name of the file?"
let filename = string (System.Console.ReadLine ())
System.Console.WriteLine "What is your needle?"
let needle = string (System.Console.ReadLine ())
System.Console.WriteLine "What you want your needle replaced with?"
let replace = string (System.Console.ReadLine ())
//Saves the content of the file
let mutable saveLine = ""
//Opens a stream to read the file
let reader = File.OpenText filename
//Reads the file, and replaces the needle.
let printFile (reader : System.IO.StreamReader) =
while not(reader.EndOfStream) do
let line = reader.ReadLine ()
let lineReplace = line.Replace(needle,replace)
saveLine <- saveLine + lineReplace
printfn "%s" lineReplace
//Opens a stream to write to the file
let readerWrite = File.CreateText(filename)
//Writes to the file
let editFile (readerWrite : System.IO.StreamWriter) =
File.WriteAllText(filename,saveLine)
printf "%A" (printFile reader)
我收到错误消息“在路径上共享违规...”,这让我相信阅读流没有正确关闭。我试过玩我的代码结构并为.NET库尝试了不同的东西,但我总是得到相同的错误消息。非常感谢任何帮助。
答案 0 :(得分:2)
通常通过调用Stream.Close()或处理它们来关闭流。
System.IO
具有从/到行数组读取或写入完整文件的方法。这会将操作缩短为:
File.ReadAllLines filePath
|> Array.map (fun line -> line.Replace(needle, replace))
|> fun editedLines -> File.WriteAllLines(filePath, editedLines)
您使用的是哪些文档?查看the MSDN documentation for System.IO和类似的MSDN文档,了解.NET / CLR中的各种内容;这些答案很快就会回答这个问题。
答案 1 :(得分:1)
我保留了大部分原始代码,虽然它不是非常惯用的。如果您使用use
一次性资源,.NET将在您之后清理。例如,请参阅F# Docs和Fun&Profit,后者在Expressions and syntax上也有一个很好的部分。
如果执行代码,则应该获得System.IO.IOException:
未处理的异常:System.IO.IOException:进程无法访问 文件'C:\ Users \ xcs \ Documents \ Visual Studio 2015年\项目\ StackOverflow6 \ ConsoleApplication11 \ BIN \发布\ testout.txt” 因为它正被另一个进程使用。在 System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)
在System.IO.FileStream.Init(字符串路径,FileMode模式,FileAccess 访问,Int32权限,布尔useRights,FileShare共享,Int32 bufferSize,FileOptions选项,SECURITY_ATTRIBUTES secAttrs,String msgPath,Boolean bFromProxy,Boolean useLongPath,Boolean checkHost)
在System.IO.FileStream..ctor(字符串路径,FileMode模式,FileAccess 访问,FileShare共享,Int32 bufferSize,FileOptions选项,字符串 msgPath,Boolean bFromProxy,Boolean useLongPath,Boolean checkHost)
在System.IO.StreamWriter.CreateFile(String path,Boolean append, System.IO.StreamWriter..ctor(String path,Boolean checkHost) 布尔附加,编码编码,Int32 bufferSize,布尔值 checkHost)在System.IO.StreamWriter..ctor(String path,Boolean 附加)在System.IO.File.CreateText(String path)at C:\ Users \ xcs \ Documents \ Visual中的Program.op@46(Unit unitVar0) 工作室 2015 \ Projects \ StackOverflow6 \ ConsoleApplication11 \ Program.fs:第74行 在C:\ Users \ xcs \ Documents \ Visual中的Program.main(String [] argv) 工作室 2015 \ Projects \ StackOverflow6 \ ConsoleApplication11 \ Program.fs:第83行
从第83行开始,这是对函数的调用,转到第74行。第74行如下:let readerWrite = File.CreateText(filename)
。您的代码中没有任何地方关闭reader
。还有一个问题,即您使用StreamWriter
打开File.CreateText
。然后你试图用File.WriteAllText
写入这个打开的流,打开文件,写入并关闭它。因此,一堆IO句柄在那里漂浮......
要快速修复它,请考虑以下事项:
//Getting the filename, needle and replace-word.
System.Console.WriteLine "What is the name of the file?"
let filename = string (System.Console.ReadLine ())
System.Console.WriteLine "What is your needle?"
let needle = string (System.Console.ReadLine ())
System.Console.WriteLine "What you want your needle replaced with?"
let replace = string (System.Console.ReadLine ())
//Saves the content of the file
//Opens a stream to read the file
//let reader = File.OpenText filename
//Reads the file, and replaces the needle.
let printFile (filename:string) (needle:string) (replace:string) =
let mutable saveLine = ""
use reader = File.OpenText filename //use will ensure that the stream is disposed once its out of scope, i.e. the functions exits
while not(reader.EndOfStream) do
let line = reader.ReadLine ()
let lineReplace = line.Replace(needle,replace)
saveLine <- saveLine + lineReplace + "\r\n" //you will need a newline character
printfn "%s" lineReplace
saveLine
//Writes to the file
let editFile filename saveLine =
File.WriteAllText(filename,saveLine) //you don't need a stream here, since File.WriteAllText will open, write, then close the file
let saveLine = printFile filename needle replace //read the file into saveLine
editFile filename saveLine //write saveLine into the file
它做了几件事:
StreamReader
printFile
use
将其绑定到读者,不要让它一旦我们不再需要它就确保关闭saveLine
封装在函数Streamwriter
删除File.WriteAllText
,并明确传入文件名和要写的字符串