Scala: load different files by input - file

My program has a lot of different functions and one of these is the command "load".
As soon as the user types as input "load" he can load in a txt file...
The problem is, that my command is not only the "load" word itself, its for example "load numbers.txt" or "load data.txt"
Now i want to open these textfiles which are located on my PC but i need the name of the files WITHOUT the "load" in front of the command. How can I fetch only the name from the entire input line?
def ProgramSelector() {
var endProgram = false
while (!endProgram) {
val userSelection = scala.io.StdIn.readLine("There is no transfer data available yet, please use the 'load' command to initialize the application!\nEnter your command or type 'help' for more information:")
if (userSelection == "help")
println("some help text here")
else if (userSelection == "load")
//else if (userSelection == "3")
//exerciseThree()
//else if (userSelection == "4")
//exerciseFour()
//else if (userSelection == "5")
//exerciseFive()
//else if (userSelection == "6")
//exerciseSix()
//else if (userSelection == "7")
//exerciseSeven()
//else if (userSelection == "8")
//exerciseEight()
else if (userSelection == "exit")
endProgram = true
else
println("Invalid command!")
So I have my function the ProgramSelector where I only make an if statement if the input is load...

I tried to make this a bit more generic.
To show how this can be helpful, I also created another command that you can call as "add 1 2" and it will print the sum of adding the two integers.
If you are serious into making a CLI interactive application, I suggest you take a look here on how to make your own interactive shell on top of sbt.
val loadCommand = """load (.*)""".r
val helpCommand = """help.*""".r
val exitCommand = """exit.*""".r
val addCommand = """add\s+(\d+)\s+(\d+)""".r
val PromptMsg = "There is no transfer data available yet, please use the 'load' command to initialize the application!\nEnter your command or type 'help' for more information: "
def programSelector() {
var endProgram = false
val fileKeeper = new scala.collection.mutable.HashSet[String]()
while (!endProgram) {
val userSelection = scala.io.StdIn.readLine(PromptMsg)
userSelection match {
case loadCommand(file) =>
println(s"Adding file $file")
fileKeeper add file
println(s"Files so far: $fileKeeper")
case helpCommand() =>
println("some help text here")
case exitCommand() =>
endProgram = true
case addCommand(a,b) =>
val sum = a.toInt + b.toInt
println(s"Sum=$sum")
case _ =>
println("Invalid command!")
}
}
}
programSelector()

Related

SSIS Flat File In Use By Another Process

I've got an SSIS package that is responsible for picking up and loading files to SQL tables, and then routing the files to various archive locations depending upon the content of the file. Prior to doing any loading, however, I have some scripts that check for various file-level errors, one of which is if the file is empty or not. I am using the following script to check if a file is empty:
Dts.Variables["blnEmptyFile"].Value = false;
Dts.Variables["User::strFileTimeStamp"].Value = "_" + DateTime.Now.ToString("yyyyMMdd") + "_" + DateTime.Now.ToString("hhmmss");
if (Dts.Variables["User::strFileRecordType"].Value.ToString() == "AF")
{
Dts.Variables["User::strFileOutToGeBBs"].Value = "AF_" + Dts.Variables["User::strCurrentFileIn"].Value.ToString().Substring(0, Dts.Variables["User::strCurrentFileIn"].Value.ToString().Length - 7) + Dts.Variables["User::strFileTimeStamp"].Value.ToString() + ".txt";
}
else if (Dts.Variables["User::strFileRecordType"].Value.ToString() == "AS")
{
Dts.Variables["User::strFileOutToGeBBs"].Value = "AS_" + Dts.Variables["User::strCurrentFileIn"].Value.ToString().Substring(0, Dts.Variables["User::strCurrentFileIn"].Value.ToString().Length - 7) + Dts.Variables["User::strFileTimeStamp"].Value.ToString() + ".txt";
}
else if (Dts.Variables["User::strFileRecordType"].Value.ToString() == "R")
{
Dts.Variables["User::strFileOutToGeBBs"].Value = "R_" + Dts.Variables["User::strCurrentFileIn"].Value.ToString().Substring(0, Dts.Variables["User::strCurrentFileIn"].Value.ToString().Length - 6) + Dts.Variables["User::strFileTimeStamp"].Value.ToString() + ".txt";
}
else
{
Dts.Variables["User::strFileOutToGeBBs"].Value = Dts.Variables["User::strCurrentFileIn"].Value.ToString().Substring(0, Dts.Variables["User::strCurrentFileIn"].Value.ToString().Length - 4) + Dts.Variables["User::strFileTimeStamp"].Value.ToString() + ".txt";
}
int nonDataRows = 1;
string ffConnection;
ffConnection = (string)(Dts.Connections["CDF_Format"].AcquireConnection(null) as string);
FileInfo flatFileInfo = new FileInfo(ffConnection);
long fileSize = flatFileInfo.Length;
if (fileSize > 0)
{
int lineCount = 0;
StreamReader fsFlatFile = new StreamReader(ffConnection);
while (!(fsFlatFile.EndOfStream))
{
Console.WriteLine(fsFlatFile.ReadLine());
lineCount += 1;
if (lineCount > nonDataRows)
{
Dts.Variables["User::blnEmptyFile"].Value = false;
break;
}
else
{
Dts.Variables["User::blnEmptyFile"].Value = true;
}
}
fsFlatFile.Close();
fsFlatFile = null;
}
else
{
Dts.Variables["User::blnEmptyFile"].Value = true;
}
Dts.TaskResult = (int)ScriptResults.Success;
After this script task, I check the blnEmptyFile variable, and if it is True, I send the empty file to a failed files folder location so that our end users can deal with it. And when I run this script inside the editor (VS 2017/2019), it runs to successful completion every single time. However, when this is run on the ETL servers, it intermittently fails with the following error:
2022-01-18 07:15:14.27 fst_ArchFailedFile:Error: An error occurred with the following error message: "The process cannot access the file because it is being used by another process.".
This only ever happens when a file is empty, and even then, it is only happening with a specific set of files that are empty. And it doesn't happen all the time; it is intermittent, and seems to want to happen on Monday (or, in the case of long weekends, Tuesday) mornings.
As you can see in the code, I am closing fsFlatFile, and I'm setting it to null. ffConnection is a string, so I can't close/kill it...although setting it to NULL has no effect either. I've tried setting a PAUSE, and that also has no effect/bearing on what is happening.
Anybody have any ideas why this would happen, and how I can resolve this? We aren't talking about Excel here (I've seen all of those posts on the internet), but simple TXT files that have only but a header and nothing else in them. Any help here would be keen.
StreamReader still has it. Try using a using block, everything inside is properly closed, disposed, etc:
using(StreamReader fsFlatFile = new StreamReader(ffConnection))
{
All the code you want to do while your stream is open.
}

How to make a discord.js bot repeat a user's message without including the prefix and command name?

Okay this most likely has a really simple answer but I couldn't find the same thing online and I can't figure it out on my own thinking.
So in the args for responding to a prefix, i have this:
case 'say':
const usermsg = message.content
message.channel.send(usermsg)
break;
Since it's the entire contents, it responds with the c!say too then it triggers itself. But the triggering isn't the issue, I want the c!say not included in the message. (I know I don't need the const for this, I just wanted to experiment different combinations of stuff in a separate line)
Update:
So I found a second method of approaching this by using the arguments part, like this:
case 'say':
message.channel.send(args[1])
message.delete(1)
break;
So this does what I want but only for the second argument, meaning it doesn't work for more than 1 word. So my current thought is subtracting args[0] (the c!say phrase) from message.content.
Found a fix to the issue, instead of sending the arguments or subtracting text I used the replace command.
case 'say':
let saymsg = message.content
message.channel.send(saymsg.replace("c!say",""))
message.delete(1)
break;
I can't believe I didn't remember the world replace sooner, but that's it, it works.
case 'say':
const usermsg = message.content.split(' ');
message.channel.send(usermsg.slice(0).join(' '));
break;
This code will take in the full user string, slice out the first argument (the command and prefix), then join the rest of the message and send it in chat.
bot.on('message', message => {
var sender = message.author;
var msg = message.content.toUpperCase();
var prefix = '>';
var cont = message.content.slice(prefix.length).split(" ");
var args = cont.slice(1);
for (x = 0; x < profanities.length; x++) {
if (message.content.toUpperCase == profanities[x].toUpperCase()) {
message.channel.send('Hey! Don\'t say that');
message.delete();
return;
}
if (msg.startsWith(prefix + 'SAY')) {
message.delete();
var saymsg = message.content;
message.channel.send(saymsg.replace(prefix + 'say', ''))
}
}
}

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)
}

Split file into the List

I have txt file for example:
useless text
-- modelName
model parameters
model parameters
-- modelName
model parameters
model parameters
e.t.c
I need to split this file into List where the elements of the list is model with model parametrs.
My algoritm for this
File(FILEPATH).eachLine { line ->
if (line =regExpForModelName) {
while(line!=regExpForModelName)
model.add(line)
}
}
while(line!=regExpForModelName) is clearly wrong
You could do it with a simple state machine like so:
enum State {
SCANNING, PARSING
}
def parseFile(String filename) {
def key = null
def result = []
def mode = State.SCANNING
new File(filename).eachLine { line ->
switch(mode) {
case State.SCANNING:
if(line.startsWith('--')) {
key = (line - '--').trim()
result << [name:key, lines:[]]
mode = State.PARSING
}
break
case State.PARSING:
if(line.size() == 0) {
mode = State.SCANNING
}
else {
result[-1].lines << line
}
}
result
}
}
def results = parseFile('/tmp/file.txt')
results.each {
println it
}
So it starts off SCANNING, and then when it finds a header item, it adds a new element to the list and switches to PARSING
Then it keeps PARSING (and adding lines to the list) until it hits an empty line, when it switches back into a SCANNING state

Not writing to the file Scala

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.

Resources