Dart file read to var - file-io

I have looked all over can not find how to read input from file into variables.
trying to do this
in c++
ifstream myFile;
myFile.open("filename.txt");
while(!file.eof()){
myFile >> var1 >> var2 >> etc...
following dart documentation ive got the file open and all but i cannot find examples likes this. would appreciate help and also links to relevant Dart examples , nothing web/app related. just trying to read from a file and do some computation with the stuff thats in the file.
(file has grades and im computing avgs).
sample input.txt file (d123 some student unique id, the numbers are grades).
d123 90 89 60 77 65 100
d124 70 79 88 75 57 89
thanks

You can find the below sample snippet. As I am not sure how big is the file, I am using async and stream API to process line by line. However, if your input is not so big, you can just read entire file at once, and perform the same step. Here are some links with good documentation dart:io, dart:convert
import 'dart:io';
import 'dart:convert';
import 'dart:async';
main(List<String> arguments) {
final file = new File('input/input.txt');
Stream<List<int>> inputStream = file.openRead();
inputStream.transform(UTF8.decoder).transform(new LineSplitter()).listen(
(String line) {
// calculate average score
List<String> list = line.split(" ");
var studentId = list[0];
var averageScore = list
.sublist(1)
.map((value) => int.parse(value))
.reduce((a, b) => a + b) / (list.length - 1);
print('${studentId} has average score of ${averageScore}');
}, onDone: () {
print('File is succeessfully read.');
}, onError: (e) {
print(e.toString());
});
}

I would just read the entire file, split into lines, and then assign variables from there:
import "dart:io";
main() {
var file = new File('input/input.txt');
var lines = file.readAsLinesSync();
var var1 = lines[0];
var var2 = lines[1];
...
}
If it's really important to read only part of the file, then you can use the solution above.

Related

Read part of binary file in Kotlin

I want to read the first 100 bytes from a binary file. I will then print them as hex. What is the most concise way to read them?
My current implementation is:
FileInputStream(File("/path/to/file")).use { stream ->
val buffer = ByteArray(100)
stream.read(buffer)
Log.d("EXAMPLE", buffer.joinToString(separator = " ") { "%02x".format(it) })
}

How to write a string to clipboard (Windows OS) with a Kotlin/Native application?

I'm very new to Kotlin and making a command line .exe, on Windows using Kotlin/Native. The application should read from a text file and print on screen, line by line. When it reaches the last line of the file, it should put it in the clipboard.
aFile.txt looks something like this:
one
two
three
...
...
the last line
and the code read.kt (Kotlin/Native) I have so far is this:
import kotlinx.cinterop.*
import platform.posix.*
fun main(args: Array<String>) {
if (args.size != 1) {
println("Usage: read.exe <file.txt>")
return
}
val fileName = args[0]
val file = fopen(fileName, "r")
if (file == null) {
perror("cannot open input file $fileName")
return
}
try {
memScoped {
val bufferLength = 64 * 1024
val buffer = allocArray<ByteVar>(bufferLength)
do {
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
if (nextLine == null || nextLine.isEmpty()) break
print("${nextLine}")
} while (true)
}
} finally {
fclose(file)
}
}
The code above prints each line on the screen, but how do I write the string "the last line" in the computer's clipboard? I'm looking for a native (not Java) solution if that's possible.
Thank you very much.
Update:
Obviously, this is not the solution I was looking for, but I don't understand yet what are they talking about here (https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setclipboarddata).
As a temporary fix, I was able to get what I needed using system(), echo and clip with code like this:
system("echo ${nextLine} | clip")
print("${nextLine}")
Try the following:
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection
fun setClipboard(s: String) {
val selection = StringSelection(s)
val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(selection, selection)
}
In Windows, you can work with the Clipboard through WinAPI, as you can see there. The reference says, that you got to use functions from the winuser.h header. This header is included in windows.h, as far as I know, so it is in your platform.windows.* package. You can approve it by checking Kotlin/Native repository files.
To clarify, what I meant, I wrote this small example of platform.windows.* usage. You can add this function to your code, and call it when you got to copy some string.
import platform.windows.*
fun toClipboard(lastLine:String?){
val len = lastLine!!.length + 1
val hMem = GlobalAlloc(GMEM_MOVEABLE, len.toULong())
memcpy(GlobalLock(hMem), lastLine.cstr, len.toULong())
GlobalUnlock(hMem)
val hwnd = HWND_TOP
OpenClipboard(hwnd)
EmptyClipboard()
SetClipboardData(CF_TEXT, hMem)
CloseClipboard()
}

Detecting file size with MultipartFormDataStreamProvider before file is saved?

We are using the MultipartFormDataStreamProviderto save file upload by clients. I have a hard requirement that file size must be greater than 1KB. The easiest thing to do would of course be the save the file to disk and then look at the file unfortunately i can't do it like this. After i save the file to disk i don't have the ability to access it so i need to look at the file before its saved to disk. I've been looking at the properties of the stream provider to try to figure out what the size of the file is but unfortunately i've been unsuccessful.
The test file i'm using is 1025 bytes.
MultipartFormDataStreamProvider.BufferSize is 4096
Headers.ContentDisposition.Size is null
ContentLength is null
Is there a way to determine file size before it's saved to the file system?
Thanks to Guanxi i was able to formulate a solution. I used his code in the link as the basis i just added a little more async/await goodness :). I wanted to add the solution just in case it helps anyone else:
private async Task SaveMultipartStreamToDisk(Guid guid, string fullPath)
{
var user = HttpContext.Current.User.Identity.Name;
var multipartMemoryStreamProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var content in multipartMemoryStreamProvider.Contents)
{
using (content)
{
if (content.Headers.ContentDisposition.FileName != null)
{
var existingFileName = content.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
Log.Information("Original File name was {OriginalFileName}: {guid} {user}", existingFileName, guid,user);
using (var st = await content.ReadAsStreamAsync())
{
var ext = Path.GetExtension(existingFileName.Replace("\"", string.Empty));
List<string> validExtensions = new List<string>() { ".pdf", ".jpg", ".jpeg", ".png" };
//1024 = 1KB
if (st.Length > 1024 && validExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase))
{
var newFileName = guid + ext;
using (var fs = new FileStream(Path.Combine(fullPath, newFileName), FileMode.Create))
{
await st.CopyToAsync(fs);
Log.Information("Completed writing {file}: {guid} {user}", Path.Combine(fullPath, newFileName), guid, HttpContext.Current.User.Identity.Name);
}
}
else
{
if (st.Length < 1025)
{
Log.Warning("File of length {FileLength} bytes was attempted to be uploaded: {guid} {user}",st.Length,guid,user);
}
else
{
Log.Warning("A file of type {FileType} was attempted to be uploaded: {guid} {user}", ext, guid,user);
}
var responseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content =
st.Length < 1025
? new StringContent(
$"file of length {st.Length} does not meet our minumim file size requirements")
: new StringContent($"a file extension of {ext} is not an acceptable type")
};
throw new HttpResponseException(responseMessage);
}
}
}
}
}
You can also read the request contents without using MultipartFormDataStreamProvider. In that case all of the request contents (including files) would be in memory. I have given an example of how to do that at this link.
In this case you can read header for file size or read stream and check the file size. If it satisfy your criteria then only write it to desire location.

Dart splits long stdout data into two ProcessResult events

When listening to a long string output from a shell process, I receive the data in two chunks. How can I get the entire text?
Here is the code in question:
int i = 0;
Process.start('perl', ['print_text.pl']).then((Process p) {
p.stdout.transform(UTF8.decoder).listen((data) => print("${i++} ${data}"));
p.stdin.writeln('print');
});
The result from running this code is:
0 text.....
1 text.....
I've reported this issue as a bug here. You can run the sample app attached to the report to see the issue.
Try using UTF8.decodeStream().
import 'dart:io';
import 'dart:convert' show UTF8;
main() {
Process.start('ls', ['-la'])
.then((p) => UTF8.decodeStream(p.stdout))
.then((s) => print('Output:\n$s'));
}
I solved this problem by doing the following:
In the shell script, tag the start and the end of the shell's output with a random number.
In Dart, concatenate all the chunks together and use the tags to check if you got the complete result.
This solution does not require exiting the process to obtain the process result.
This is a sample code:
String text = '';
process.stdout.transform(UTF8.decoder).listen((String chunk) {
text = text + chunk;
if (text.substring(errors.length - 1) == text.substring(0, 1)) {
text = text.replaceFirst(new RegExp(r'^(\d+)'), '').replaceFirst(new RegExp(r'(\d+)$'), '');
// use process result then clear text value for subsequent process results
text = '';
}
});
It's not clear what the actual question is but I assume this is what you are looking for:
import 'dart:io';
import 'dart:convert' show UTF8;
void main() {
int i = 0;
String text = '';
Process.start('perl', ['analyze.pl']).then((p) {
p.stdout.transform(UTF8.decoder).listen((data) =>
text += data);
p.exitCode.then((_) => print(text));
});
}

Identify and extract or delete pages of a PDF based on a search string / text (action / javascript)

Good Evening (UK)
I'm trying to filter down a 1500+ page PDF file to only the pages which include a certain text string (typically one or two words). My laptop is locked down with respect to installing more software BUT I have used action(script)s quite a bit
I get the error below when I try to install this action into Abobe Acrobat X Pro (Win 7):
screen dump of error
called "Extract Commented Pages"... supposed to be OK for X and XI this looks like what I want.....
I wondered if there was something simple causing the problem but the actionscript file is rather... busy to say the least.
I used to have an action that I think was based on a legal redaction script but it is filed somewhere!
If you have already got an action that does this or a version of the above that doesn't give the error I get (unable to import the Action.... The file is either invalid or corrupt) I will forever by indebted to your gratitude
Many thanks, have a good weekend!
I recently came across a script found at the following link: http://forums.adobe.com/thread/1077118
I'm having some issues getting the script to run in Acrobat, despite everything looking alright in the script itself. I'll update if I find any errors.
Here is a copy of the script:
// Set the word to search for here
var sWord = "forms";
// Source document = current document
var sd = this;
var nWords, currWord, fp, fpa = [], nd;
var fn = sd.documentFileName.replace(/\.pdf$/i, "");
// Loop through the pages
for (var i = 0; i < sd.numPages; i += 1) {
// Get the number of words on the page
nWords = sd.getPageNumWords(i);
// Loop through the words on the page
for (var j = 0; j < nWords; j += 1) {
// Get the current word
currWord = sd.getPageNthWord(i, j);
if (currWord === sWord) {
// Extract the current page to a new file
fp = fn + "_" + i + ".pdf";
fpa.push(fp);
sd.extractPages({nStart: i, nEnd: i, cPath: fp});
// Stop searching this page
break;
}
}
}
// Combine the individual pages into one PDF
if (fpa.length) {
// Open the document that's the first extracted page
nd = app.openDoc({cPath: fpa[0], oDoc: sd});
// Append any other pages that were extracted
if (fpa.length > 1) {
for (var i = 1; i < fpa.length; i += 1) {
nd.insertPages({nPage: i - 1, cPath: fpa[i], nStart: 0, nEnd: 0});
}
}
// Save to a new document and close this one
nd.saveAs({cPath: fn + "_searched.pdf"});
nd.closeDoc({bNoSave: true});
}