Not writing to the file Scala - file

I have the following code, which is supposed to write to a file one line at a time, until it reaches ^EOF.
import java.io.PrintWriter
import java.io.File
object WF {
def writeline(file: String)(delim: String): Unit = {
val writer = new PrintWriter(new File(file))
val line = Console.readLine(delim)
if (line != "^EOF") {
writer.write(line + "\n")
writer.flush()
}
else {
sys.exit()
}
}
}
var counter = 0
val filename = Console.readLine("Enter a file: ")
while (true) {
counter += 1
WF.writeline(filename)(counter.toString + ": ")
}
For some reason, at the console, everything looks like it works fine, but then, when I actually read the file, nothing has been written to it! What is wrong with my program?

Every time you create a new PrintWriter you're wiping out the existing file. Use something like a FileWriter, which allows you to specify that you want to open the file for appending:
val writer = new PrintWriter(new FileWriter(new File(file), true))
That should work, although the logic here is pretty confusing.

Use val writer = new FileWriter(new File(file), true) instead. The second parameter tells the FileWriter to append to the file. See http://docs.oracle.com/javase/6/docs/api/java/io/FileWriter.html

I'm guessing the problem is that you forgot to close the writer.

Related

How to read plain text file in kotlin?

There may be various way to read plain text file in kotlin.
I want know what are the possible ways and how I can use them.
1. Using BufferedReader
import java.io.File
import java.io.BufferedReader
fun main(args: Array<String>) {
val bufferedReader: BufferedReader = File("example.txt").bufferedReader()
val inputString = bufferedReader.use { it.readText() }
println(inputString)
}
2. Using InputStream
Read By Line
import java.io.File
import java.io.InputStream
fun main(args: Array<String>) {
val inputStream: InputStream = File("example.txt").inputStream()
val lineList = mutableListOf<String>()
inputStream.bufferedReader().forEachLine { lineList.add(it) }
lineList.forEach{println("> " + it)}
}
Read All Lines
import java.io.File
import java.io.InputStream
fun main(args: Array<String>) {
val inputStream: InputStream = File("example.txt").inputStream()
val inputString = inputStream.bufferedReader().use { it.readText() }
println(inputString)
}
3. Use File directly
import java.io.File
import java.io.BufferedReader
fun main(args: Array<String>) {
val lineList = mutableListOf<String>()
File("example.txt").useLines { lines -> lines.forEach { lineList.add(it) }}
lineList.forEach { println("> " + it) }
}
I think the simplest way to code is using kotlin.text and java.io.File
import java.io.File
fun main(args: Array<String>) {
val text = File("sample.txt").readText()
println(text)
}
The answers above here are all based on Kotlin Java. Here is a Kotlin Native way to read text files:
val bufferLength = 64 * 1024
val buffer = allocArray<ByteVar>(bufferLength)
for (i in 1..count) {
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
if (nextLine == null || nextLine.isEmpty()) break
val records = parseLine(nextLine, ',')
val key = records[column]
val current = keyValue[key] ?: 0
keyValue[key] = current + 1
}
fun parseLine(line: String, separator: Char) : List<String> {
val result = mutableListOf<String>()
val builder = StringBuilder()
var quotes = 0
for (ch in line) {
when {
ch == '\"' -> {
quotes++
builder.append(ch)
}
(ch == '\n') || (ch == '\r') -> {}
(ch == separator) && (quotes % 2 == 0) -> {
result.add(builder.toString())
builder.setLength(0)
}
else -> builder.append(ch)
}
}
return result
}
See: https://github.com/JetBrains/kotlin-native/blob/master/samples/csvparser/src/csvParserMain/kotlin/CsvParser.kt
Anisuzzaman's answer lists several possibilities.
The main differences between them are in whether the file is read into memory as a single String, read into memory and split into lines, or read line-by-line.
Obviously, reading the entire file into memory in one go can take a lot more memory, so that's something to avoid unless it's really necessary.  (Text files can get arbitrarily big!)  So processing line-by-line with BufferedReader.useLines() is often a good approach.
The remaining differences are mostly historical.  Very early versions of Java used InputStream &c which didn't properly distinguish between characters and bytes; Reader &c were added to correct that.  Java 8 added ways to read line-by-line more efficiently using streams (e.g. Files.lines()).  And more recently, Kotlin has added its own extension functions (e.g. BufferedReader.useLines()) which make it even simpler.
To read a text file, it must first be created. In Android Studio, you would create the text file like this:
1) Select "Project" from the top of the vertical toolbar to open the project "tool window"
2) From the drop-down menu at the top of the "tool window", select "Android"
3) Right-click on "App" and select "New"
then -> "Folder" (the one with the green Android icon beside it)
then -> "Assets Folder"
4) Right-click on the "assets" folder after it appears in the "tool window"
5) Select "New" -> "File"
6) Name the file, and included the extension ".txt" if it is text file, or ".html" if it is for WebView
7) Edit the file or cut and paste text into it. The file will now display under the "Project" files in the "tool window" and you will be able to double-click it to edit it at any time.
TO ACCESS THIS FILE, use a prefix of "application.assets." followed by someFunction(fileName). For example (in Kotlin):
val fileName = "townNames.txt"
val inputString = application.assets.open(fileName).bufferedReader().use { it.readText() }
val townList: List<String> = inputString.split("\n")
how to apply Documents path on that:
fun main(args: Array<String>) {
val inputStream: InputStream = File("example.txt").inputStream()
val inputString = inputStream.bufferedReader().use { it.readText() }
println(inputString)
}

Groovy script to modify text file line by line

I have a input file from which a Groovy file reads input. Once a particular input is processed, Groovy script should be able to comment the input line it used and then move on.
File content:
1
2
3
When it processes line 1 and line 2, the input file will look as below:
'1
'2
3
By this way, if I re-run the Groovy, I would like to start from the line it stopped last time. If a input was used and it failed, that particular line shall not be commented (') so that a retry can be attempted.
Appreciate if you can help to draft a Groovy script.
Thanks
AFAIK in Groovy you can only append text at the end of the file.
Hence to add ' on each line when it is processed you need to rewrite the entire file.
You can use the follow approach but I only recommend you to use for a small files since you're loading all the lines in memory. In summary an approach for your question could be:
// open the file
def file = new File('/path/to/sample.txt')
// get all lines
def lines = file.readLines()
try{
// for each line
lines.eachWithIndex { line,index ->
// if line not starts with your comment "'"
if(!line.startsWith("'")){
// call your process and make your logic...
// but if it fails you've to throw an exception since
// you can not use 'break' within a closure
if(!yourProcess(line)) throw new Exception()
// line is processed so add the "'"
// to the current line
lines.set(index,"'${line}")
}
}
}catch(Exception e){
// you've to catch the exception in order
// to save the progress in the file
}
// join the lines and rewrite the file
file.text = lines.join(System.properties.'line.separator')
// define your process...
def yourProcess(line){
// I make a simple condition only to test...
return line.size() != 3
}
An optimal approach to avoid load all lines in memory for a large files is to use a reader to read the file contents, and a temporary file with a writer to write the result, and optimized version could be:
// open the file
def file = new File('/path/to/sample.txt')
// create the "processed" file
def resultFile = new File('/path/to/sampleProcessed.txt')
try{
// use a writer to write a result
resultFile.withWriter { writer ->
// read the file using a reader
file.withReader{ reader ->
while (line = reader.readLine()) {
// if line not starts with your comment "'"
if(!line.startsWith("'")){
// call your process and make your logic...
// but if it fails you've to throw an exception since
// you can not use 'break' within a closure
if(!yourProcess(line)) throw new Exception()
// line is processed so add the "'"
// to the current line, and writeit in the result file
writer << "'${line}" << System.properties.'line.separator'
}
}
}
}
}catch(Exception e){
// you've to catch the exception in order
// to save the progress in the file
}
// define your process...
def yourProcess(line){
// I make a simple condition only to test...
return line.size() != 3
}

Getting path of audio file from sdcard

In my app I tried to pass the file path from one activity to another activity using intent.In my receiving activity I got the file path as "null".But when I print the file in first activity it prints the path.From my second activity I attach that file to mail using Gmailsender.This was the code I tried,
private void startRecord()
{
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
try
{
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
audioRecord.startRecording();
while(recording)
{
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++)
{
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
audioRecord.release();
dataOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
String audiofile;
audiofile=file.getAbsolutePath();
System.out.println("File Path::::"+audiofile);
}
Intent is,
Intent sigout=new Intent(getApplicationContext(),WeeklyendActivity.class);
sigout.putExtra("mnt/sdcard-test.pcm",audiofile);
startActivity(sigout);
In my receiving activity,
String patty=getIntent().getStringExtra("mnt/sdcard-text.pcm");
System.out.println("paathhhy frfom ::"+patty);
It prints null.Can anyone help me how to get the file path.And more thing I am not sure whether the audio would save in that file correctly?
Please anyone help me!!!Thanks in advance!
Based on your information that audioFile is a variable of type File, when you do this:
sigout.putExtra("mnt/sdcard-test.pcm",audiofile);
you are putting a File object in the extras Bundle. Then, when you try to get the extra from the Bundle you do this:
String patty=getIntent().getStringExtra("mnt/sdcard-text.pcm");
However, the object in this extra is of type File, not type String. This is why you are getting null.
If you only want to pass the name of the file, then put the extra like this:
sigout.putExtra("mnt/sdcard-test.pcm",audiofile.getAbsolutePath());

How to split a File Source into Strings or Words

I have a file with content like this:
"Some","Words","separated","by","comma","and","quoted","with","double","quotes"
The File is to large to read it into just on String.
What is the simplest way to split it into a Traversable of Strings, with each element being a word?
If it matters: While the content of the file won't fit in a single String the resulting Traversable might be a List without a problem.
Here is an adaptation of your own solution, using JavaConversions to manipulate the Java iterator as a Scala one.
import java.util.Scanner
import java.io.File
import scala.collection.JavaConversions._
val scanner = new Scanner(new File("...")).useDelimiter(",")
scanner.map(_.trim).map(quoted => quoted.substring(1, quoted.length - 1))
This gives you an iterator. You can always convert it to a list using e.g. .toList.
Here is a version using stringLit and repsep from Scala parser combinators. I won't vouch for its efficiency, though.
import scala.util.parsing.combinator.syntactical.StdTokenParsers
import scala.util.parsing.combinator.lexical.StdLexical
import scala.util.parsing.input.StreamReader
import java.io.FileReader
object P extends StdTokenParsers {
type Tokens = StdLexical
val lexical = new StdLexical
lexical.delimiters += ","
def words : Parser[List[String]] = repsep(stringLit, ",")
def getWords(fileName : String) : List[String] = {
val scanner = new lexical.Scanner(StreamReader(new FileReader(fileName)))
// better error handling wouldn't hurt.
words(scanner).get
}
}
I did it using the java.util.Scanner while it does work, I'd appreciate a more scalaesc version.
val scanner = new Scanner(new File("""bigFile.txt""")).useDelimiter(",")
var wordList: Vector[String] = Vector()
while (scanner.hasNext()) {
val quoted = scanner.next()
val word = quoted.replace("\"", "")
wordList = wordList :+ word
}

FileStream seems to find an unexisting file

I have this code:
public static string GetUserEmail()
{
string path = Application.StartupPath + "\\mail.txt";
MessageBox.Show(path);
string adres = String.Empty;
if (File.Exists(path))
{
using (StreamReader sr = new StreamReader(path))
{
adres = sr.ReadLine();
}
}
else
{
using (FileStream fs = File.Create(path))
{
using (StreamReader sr = new StreamReader(path))
{
adres = sr.ReadLine();
}
}
}
MessageBox.Show(adres);
return adres;
}
I checked the ApplicationPath with the MessageBox.Show(); as you can see, go there and delete the file, re-launch the app, and it still reads the previous line . I uninstall the app re-install and still seems to find the file and read the same line I have entered in the very first installation. I searched windows, the whole C drive, there is no mail.txt and it still finds the mail.txt and reads the line (a email address, used to identify the user)
What can it be? aliens?
Firstly, which code route does the program take? The one where the file is created, or the one where the existing file is read?
Try placing a breakpoint just before the existance of the file is checked and then go and check at that point if the file exists or not.
Do you have any code elsewhere that creates and writes the file, as part of the application startup?
Otherwise, its definitely aliens.

Resources