У меня есть приложение, в котором я должен записать значения в файл и прочитать их обратно в программу в цикле while.Это не удается, потому что файл записывается только после выхода из цикла, а не на каждой итерации.Поэтому на следующих итерациях я не могу получить доступ к значениям, которые должны были быть записаны в файл на предыдущих итерациях.Как сделать так, чтобы каждая итерация записывала в файл, а не записывала все значения в конце цикла while?
Мое приложение использует Scalafix.Он читает файл Scala набора тестов и дублирует свои тестовые примеры на каждой итерации.Важные детали объясняются моей серией из 8 комментариев.Есть ли что-то в работе FileWriter, которая заставляет его ждать до последнего цикла цикла для обратной записи в файл, поскольку он не записывает обратно в файл на каждой итерации цикла?
object Printer{
//1 . This is my filePrinter which I call at every iteration to print the new test file with its test cases duplicated.
def saveFile(filename:String, data: String): Unit ={
val fileWritter: FileWriter = new FileWriter(filename)
val bufferWritter: BufferedWriter = new BufferedWriter(fileWritter)
bufferWritter.write(data)
bufferWritter.flush()
bufferWritter.close()
}
}
object Main extends App {
//2. my loop starts here.
var n = 2
do {
// read in a semanticDocument (function provided below)
val ( sdoc1,base,filename)=SemanticDocumentBuilder.buildSemanticDocument()
implicit val sdoc = sdoc1 //4. P3 is a scalafix "patch" that collects all the test cases of
// test suite and duplicates them. It works just fine, see the next comment.
val p3 =sdoc.tree.collect {
case test@Term.ApplyInfix(Term.ApplyInfix(_,Term.Name(smc), _,
List(Lit.String(_))), Term.Name("in"), _, params) =>
Patch.addRight(test,"\n" +test.toString())
}.asPatch
//5. I collect the test cases in the next line and print
//out how many they are. At this moment, I have not
// applied the duplicate function, so they are still as
//originally read from the test file.
val staticAnalyzer = new StaticAnalyzer()
val testCases: List[Term.ApplyInfix] =
staticAnalyzer.collectTestCases()
println("Tests cases count: "+ testCases.length)
val r3 = RuleName(List(RuleIdentifier("r3")))
val map:Map[RuleName, Patch] = Map(r3->p3)
val r = PatchInternals(map, v0.RuleCtx(sdoc.tree), None)
//6. After applying the p3 patch in the previous three lines,
//I indeed print out the newly created test suite file
//and it contains each test case duplicated as shown
// by the below println(r._1.getClass).
println(r._1.getClass)
//7. I then call the my save file (see this function above - first lines of this code)
Printer.saveFile(base+"src/test/scala/"+filename,r._1)
n-=1
//8. Since I have saved my file with the duplicates,
//I would expect that it will save the file back to the
//file (overwrite the original file as I have not used "append = true".
//I would then expect that the next length of test cases will
//have doubled but this is never the case.
//The save function with FileWriter only works in the last loop.
//Therefore, no matter the number of loops, it only doubles once!
println("Loop: "+ n)
} while(n>0)
}
** Редактировать с учетом чтения semanticDocument
** Эта функция просто возвращает SemanticDocument
и две строки, представляющие мой путь к файлу и имя файла.
object SemanticDocumentBuilder{
def buildSemanticDocument(): (SemanticDocument,String,String) ={
val base = "/Users/soft/Downloads/simpleAkkaProject/"
val local = new File(base)
//val dependenceisSBTCommand = s"sbt -ivy ./.ivy2 -Dsbt.ivy.home=./.ivy2 -Divy.home=./.ivy2
//val sbtCmd = s"sbt -ivy ./ivy2 -Dsbt.ivy.home=./ivy2 -Divy.home=./ivy2 -Dsbt.boot.directo
val result = sys.process.Process(Seq("sbt","semanticdb"), local).!
val jars = FileUtils.listFiles(local, Array("jar"), true).toArray(new Array[File](0))
.toList
.map(f => Classpath(f.getAbsolutePath))
.reduceOption(_ ++ _)
val classes = FileUtils.listFilesAndDirs(local, TrueFileFilter.INSTANCE, DirectoryFileFilte
.toList
.filter(p => p.isDirectory && !p.getAbsolutePath.contains(".sbt") && p.getAbsolutePath.co
.map(f => Classpath(f.getAbsolutePath))
.reduceOption(_ ++ _)
val classPath = ClassLoader.getSystemClassLoader.asInstanceOf[URLClassLoader].getURLs
.map(url => Classpath(url.getFile))
.reduceOption(_ ++ _)
val all = (jars ++ classes ++ classPath).reduceOption(_ ++ _).getOrElse(Classpath(""))
val symbolTable = GlobalSymbolTable(all)
val filename = "AkkaQuickstartSpec.scala"
val root = AbsolutePath(base).resolve("src/test/scala/")
println(root)
val abspath = root.resolve(filename)
println(root)
val relpath = abspath.toRelative(AbsolutePath(base))
println(relpath)
val sourceFile = new File(base+"src/test/scala/"+filename)
val input = Input.File(sourceFile)
println(input)
if (n == firstRound){
doc = SyntacticDocument.fromInput(input)
}
//println(doc.tree.structure(30))
var documents: Map[String, TextDocument] = Map.empty
Locator.apply(local.toPath)((path, db) => db.documents.foreach({
case document@TextDocument(_, uri, text, md5, _, _, _, _, _) if !md5.isEmpty => { // skip
if (n == firstRound){
ast= sourceFile.parse[Source].getOrElse(Source(List()))
}
documents = documents + (uri -> document)
println(uri)
}
println(local.canWrite)
if (editedSuite != null){
Printer.saveFile(sourceFile,editedSuite)
}
}))
//println(documents)
val impl = new InternalSemanticDoc(doc, documents(relpath.toString()), symbolTable)
implicit val sdoc = new SemanticDocument(impl)
val symbols = sdoc.tree.collect {
case t@ Term.Name("<") => {
println(s"symbol for $t")
println(t.symbol.value)
println(symbolTable.info(t.symbol.value))
}
}
(sdoc,base,filename)
}
}