Hi ddanbe, thanks for your answer.
I can the function inside start button like this

await Task.Run(() => MyFunction(filename, cts.Token), cts.Token);

But the processing is done in the function, so I check the number of while loops inside the "while" that is in the function. How can I monitor the number of loops creating the progressbar inside the code of start button?

or when you say, create it in the same thread, is not needed to created inside the same Star button code where I call the "MyFunction()"?

Maybe you can help me with a little example.

Thanks in advance.

I'm trying to add a progress bar to a working theaded program that uses a cancelation token too. The structure of the program is:
I have a button "BeginButton" that calls the function "MyFunction()". The function runs in another thread and
a cancellation token listens if I press a Cancel button. I needed to add the thread since the UI freezes when
MyFunction() runs and I wasn't able to stop it.

Since the MyFunction() reads a file in chunks of 1024 bytes, my logic to show the progress is get the 1% of
File.Length and check when the loop increases each 1% of File size. Then I increment the progressBaar1
when Module of "BytesRead" and "(1% of File size)" = 0, this is "BytesRead % OnePercent == 0". This logic
works in a program that doesn't use threads, but in my code with thread is not working.

How can I add the progress bar to my code?

I've added the progressBar1 control to the Form and added this code inside the while loop of my threaded program.

FileLength = (int)reader.BaseStream.Length; //Filename size
//Getting the 1% of FileName size
decimal OnePercent = Math.Truncate((Decimal)(FileLength/1024)/100); 

if ( BytesRead % OnePercent == 0 && progressBar1.Value < 100)
{
    progressBar1.Value++;
    progressBar1.CreateGraphics().DrawString(
                    progressBar1.Value.ToString() + "%", 
                    new Font("Arial",(float)8.25),Brushes.Black,100,5);
}                       
BytesRead++;    

But I get this error:

System.Reflection.TargetInvocationException: 
Exception has been thrown by the target of an invocation. 
---> System.InvalidOperationException: 
Cross-thread operation not valid: Control 'progressBar1' accessed from a thread 
other than the thread it was created on.
at ...

Hello cgeier, I only check how increases the output file in windows explorer in size field. One method makes it grows up in KB and the other in MB.

Thanks rubberman and ddanbe again, it seems the issue was that I was open the writer each time I print. Then I defined only once the writer and I close it at the very end and this time it works so nice.

Thanks for your help.

Hi ddanbe,

Thanks for answer. I've followed what you said and I increased the buffer size to 64KB, 128KB and nothing happens, the speed it seems to be the same, the output file still grows up in 30KB or 40KB per second.

I did like this:

    using (StreamWriter writer = new StreamWriter(@"C:\OuputFile.txt", true, Encoding.UTF8, 65536))

Thanks again.

Hello to all, I'm trying to use the function below to print strings to a file. When I use Console.Write() or
Console.WriteLine() the output file grows up 3MB or 4MB per seconds, but when I try to use StreamWriter or
File.AppendAllText the output in the way shown below, the file grows up only in 20KB or 30KB per second.

Why the print speed decreases too much when I use StreamWriter instead of Console.WriteLine()?
What method should I use to write to a file maintaining the same speed of Console.WriteLine()?

    public static void PrintFunction()
    {            
        //using (StreamWriter writer = File.AppendText(@"C:\OuputFile.txt"))
        using (StreamWriter writer = new StreamWriter(@"C:\OuputFile.txt", true))
        {            
            //Console.Write("This is "); // Print speed is about 3MB-4MB per second
            writer.Write("This is "); //Print decreases to 20KB-30KB per second
            //File.AppendAllText(@"C:\OuputFile.txt", "This is "); Print decreases to 20KB-30KB per second

            // SOME CODE
            // SOME CODE

            //Console.WriteLine("the first line"); // Print speed is about 3MB-4MB per second
            writer.WriteLine("the first line"); // Print decreases to 20KB-30KB per second
            //File.AppendAllText(@"C:\OuputFile.txt", "the first line"); // Print decreases to 20KB-30KB per second
        }
    }

Thanks in advance.

Hello Suzie,

Thanks for point me with C#, I've been learning and trying and yes, the PCRE regex worked fine.

I'm researching to trying to get my goal.

Thanks again.

Regards

Hello Suzie,

Many thanks for your suggestion. I think C and C++ for what I investigated, don't handle lookbehind, lookahead or PCRE compatible regex. I'll check about C# since you mention that is very very easy to create a GUI :).

Regards

Hello Nathan,

Thanks for your answer.

The issue is the source code is in Ruby and in Ruby I cannot do it a GUI directly without use another 3rd party tool that I don't know which could be better without the need to re-do de Ruby code.

The code in Ruby is short and uses regex that C cannot handle and replicate what the Ruby code does using regex in another language without Regex complicates a lot the algorithm. I've been trying to replicate the code in java but still pending a lot of things, due to that I thougth in create a simple GUI to handle/call the exe file.

Regards

Hello Nathan,

Thanks for your answer. I understand from your answer that would be better to make a windows with input boxes, buttons etc and one of those buttons associate it with a command to call the "program.exe" each time is needed? it is correct?

I'm not expert in programming, do you know if could be "easier" make a simple GUI to call the "program.exe" in C++ or java or in another language?

Thanks for help me begin with this project.

Thanks again for your help.

Hello to all,

I have a console executable file that I run from DOS console passing some options
and an input file. I'd like to give to this exe file a GUI.

I'd like that the GUI was a new exe file that could contain inside my console exe file
and run the console exe from the GUI, having the console exe file inside of the GUI file.

Is possible to do this with C++?

Please suggestions.

Thanks in advance.

Regards

Hello James, thanks for your good answer. I've added the code you shared and it works if the input is text file, but fails with the binary, confirming that scanner doesn't work with binaries.

Besides your other way you suggest (read byte by byte), I've been testing with RamdonAccesFile and Inputstream (as shown in first post) reading in blocks of 1024 bytes. The idea is almost working, but I'm failing since it happens as follow.

1- In first iteration I read 1024 bytes and result 4 sequences of D2A7, resulting in 3 complete chunks and 1 incomplete chunk (224 bytes).
2- Then, from those 1024 bytes I really parse 800 bytes.
3- Now I'd would like to read another 1024 bytes but not beginning in the byte 1025, but beggining in the byte 800. This is order to analyse completely the chunk #4 that was incomplete in first iteration.
The problem is I don't know which method use to say to Java to read groups of 1024 bytes, but beginning in different positions each time (variable offset).

For example:

  • In 1rst iteration read 1024 bytes to buffer with offset=0 bytes
  • In 2nd iteration read 1024 bytes to buffer with offset=800 bytes
  • In 3rd iteration read 1024 bytes to buffer with offset=1540 bytes

The offset would be taking as reference the beginning of file.

Is there a method, function to do this?

I've tried in the code in my original post using the variable "lastPos" but
is not ...

Hello James,

Actually all the content of the file is binary, but if the scanner is able to use delimiter such as the sequence 0xD20xA7 and return each token as documentation says, I'd be able to convert that token into hexadecimal string.

I'm trying with code below, but I cannot test the code since appear a message that says "No suitable constructor found for scanner".

How would be the correct way to set the scanner to analyse the binary file?

Thanks for any help

package binaryscanner;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class BinaryScanner {
    public static void main(String[] args) throws FileNotFoundException {
     Scanner input = new Scanner(new File("./binary"));
        try (Scanner s = new Scanner(input).useDelimiter("0xDA0xA7")) {
            System.out.println(s.next());
        }         
    }    
}

Regards

Hello to all in forum,

Maybe some java expert could help me.

How can I read chunks from binary file each chunk at a time? The chunks are separated with the
bytes D2 followed by A7 and of variable length. This is whenever D2A7 is found, this is the End/Beginning of a new chunk.

The code I have so far is below and in general does this:

1- Store 1024 bytes in "inputBytes" for each for loop
2- Convert to a hexadecimal string the content of "inputBytes"
3- Replace all the "E8F5" with carriage return \r (in order to be able to use scanner.nextLine feature )

The issue is the last chunk in each iteration of 1024 bytes is incomplete and is needed a way to read 1024
each time and give the offset, but the form "read(inputBytes,Pos,1024)" is not working.

May somebody has an alternative way to do it or how to fix my code. The code is below:

package ReadbyChunks;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import javax.xml.bind.DatatypeConverter;

public class ReadbyChunks {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        // TODO code application logic here
        File inputFile = new File("./binary");
        int lastPos = 0; //To store position of last delimiter

        try (InputStream input = new FileInputStream(inputFile)) {    
            for(int i=1; i<3; i++){ //Loop to read more than one chunk
                byte inputBytes[] = new byte[1024];
                int readBytes = input.read(inputBytes); // Storing 1024 bytes in "inputBytes"
                //Converting ...

Hello L7Sqr,

The XML has elements with chil elements that happens only once, like Date, File name, Store Name, etc. But other child elements always could have one or more elements since are related with activities or codes that could happen once or more times. Is the way it is the XML file due to the content that stores.

Do you know if REXML is a good option to work with? or do you know another pacakge to parse XML that could be easier or faster or with better features?.

Thanks for the help.

Regards

Hello L7Sqr,

Thanks for the nice explanation. I understand much better your code. Normally the compacted syntax trends to confuse me, but with your explanation I understood :).

What I'm trying to do is parse an XML file with REXML module and the issue is that some nodes happens one time and others child elements happens several times.

The values of each element is captured in an array and when I have completely filled the array, I want to print in that way. I mean, each array inside the array contains all values for each child element (one value or more if it is repeated).

Then, I need to finally transpose the arrays to print them as I asked at the beginnig of the post, but in order to use "transpose" method, I need to have all arrays of the same size. Because of that, the way I think is filling the smaller arrays with blanks.

Certainly there are stright ways to accomplish the parsing I'm trying, but due to my lack of knowdledge in ruby I go completing parts of my algorithm step by step. If I had more knowledge maybe seeing globally the problem, I'd do it in a another way :).

Many thanks for your help ant time again

Hello L7Sqr,

I'm trying with code below, but I get error "Can't convert string into array (TypeError)"

#!/usr/bin/env ruby
require 'matrix'

 def ExtendedMatrix( *rows )
 maxWid = rows.collect { |r| r.size }.max
 Matrix[ *(rows.collect { |r| while r.size < maxWid do r + "" end  }) ]
 end

p ExtendedMatrix( [1,2,3], [2,3,4,5,6], [3,4,5] )

How to fix this?

Thanks in advance

Hello L7sqr,

I've tried to modify your code, but I don't understand how operates the code you have shared nor collect and the *.

I have this so far, I think that "maxWid = rows..{...}max" to get the max could be ok, but I don't get how to add the difference how you say (array#+).

#!/usr/bin/env ruby
require 'matrix'

 def trimmedMatrix( *rows )
 maxWid = rows.collect { |r| r.size }.max
 Matrix[ *(rows.collect { |r| r[0...maxWid] }) ]
 end

 p trimmedMatrix( [1,2,3], [2,3,4,5,6], [3,4,5] )

Thanks for help so far.

Hello L7Sqr,

Thanks for the example. This works for the trimming part, but how to add the trimmed elements and empty elements for smaller arrays?

I mean, having this original matrix:

  m = [[1,2,3], [2,3,4,5,6], [3,4,5] ]

The first step as you suggest is trim to the smaller array size to get this trimmed matrix:

  trimmed_m = [[1,2,3], [2,3,4], [3,4,5]]

But the final matrix I want to get is:

 final_m = [[1,2,3,"",""], [2,3,4,5,6], [3,4,5,"",""]]

Having this final matrix with all arrays with the same size, I'd be able to use the transpose method you shared to print in parallel.

Thanks again for the help

Hello L7Sqr,

Thanks again for the help and time.

Which method could wrap the matrix creation?

Regards

Hello L7Sqr,

Thanks for answer.

May you explain how it works your code. I undertand that "hash.keys.size" counts how many keys exist inside the hash (in this case 4) and "times" is the way to say loop 4 times. But I don't undertand clearly how "hash.collect" method works yet.

Besides this, I've done a little change to key "C" adding a new element, but this time I still getting the same output as for the original hash.

I.ve modified the hash like this (added "5" as last element in "C"):

hash = {"A"=>["HYU"], "B"=>["TU6"], "C"=>["11", "09","88","2","5"], "D"=>["01", "11"]}

And the output I receive is the same:

A,B,C,D
HYU,TU6,11,01
,,09,11
,,88,
,,2, 

When the output expected is:

A,B,C,D
HYU,TU6,11,01
,,09,11
,,88,
,,2, 
,,5,

How to fix this?

Thanks in advance.

Hello to all,

HAving a hash where its keys are associated with arrays like below:

myHash = {"A"=>["HYU"], "B"=>["TU6"], "C"=>["11", "09","88","2"], "D"=>["01", "11"]}

Each key represent one header and the arrays elements represent the values for each header.

How to print each key in different column separated by comma "," and below each header print all the values of
corresponding array. Since some arrays have more elements, for the arrays that have less elements print blank
like below.

A,B,C,D
HYU,TU6,11,1
,,9,11
,,8,
,,2,

Thanks in advance for any help.

Hello L7sqr,

Thanks for your contribution. Always is good to know more ways to do something.

I've been trying your code and it works just fine. Doing manually I see that in order to work with this matrix method, is needed that all arrays have the same size. I was wondering how to print in parallel arrays that have different size.

I can think that first should be known the arrays with more number of elements and then fill with blanks the other arrays to make them of the same size.

Something like convert this:

m = Matrix[ [1,2,3], [2,3,4], [3,4,5], [4,5,6] ]

to this:

m = Matrix[ [1,2,3,""], [2,3,4,0], [3,4,5,""], [4,5,6,""] ]

How can I do this?
How many arrays does accept Matrix[...]?

Thanks in advance for your help.

Regads

Thanks so much sepp2k. I'll check zip documentation to make some tests.

Best regards

Hello again sepp2k,

It works!

Only to know in general, how would be if I have 3 or more arrays and I wanted to print in parallel?

Thanks again for the help.

Hello to all,

Having to arrays of the same size like below.

A = ["SL","MW","OP"]
B = ["RU","YF","L2"]

How can I concatenate in columns to print in parallel like below?

SL - RU
MW - YF
OP - L2

I've tried with code below but is printing all in one column

puts A << "-" << B

Thanks in advance for any help.

Hi sepp2k,

Thank you! it works now. The issue I had it was that I was putting the hash argument with uppercase and it was being detected as constant.

I changed to lowercase and it worked.

Many thanks for your help.

Hello sepp2k,

It was a typo about hash and myHash, but is not working yet like this:

Array_A = []
def load_values(myHash)
    myHash.keys.each do |z|
        Array_A << "This is key " + z
    end
end             

myHash = {
                "x1" => "2",
                "x2" => "0",
                "x3" => "1",
                .
                .
                .
                "X350" => "1"
                }

load_values(myHash)

puts myHash.values.join("|")                            
puts Array_A.join("|")

I want to start with an empty array and return the array as result to print the content of Array_A at the end joining it with "|", but I'm not sure how is the correct way to do it inside the method.

Should I to pass as argument the array too?

Is not working yet.

This is what I have so far.

Array_A = []
def load_values(hash={})
    myHash.keys.each do |z|
        Array_A << "This is key " + z
    end
end             

myHash = {
                "x1" => "2",
                "x2" => "0",
                "x3" => "1",
                .
                .
                .
                "X350" => "1"
                }

load_values(myHash)

puts myHash.values.join("|")                            
puts Array_A.join("|")

Thanks again for the help

Hello sepp2k,

Thanks for answer.

I'm a kind of new into Ruby.

How would do the way to do it? I've tried some way but I cannot paste the code for you to see it
since the toolbar Code button is not working.

Thanks again

Hello to all,

I have a ruby script with a very long hash with more than 300 associations.
The script looks like below:

#!/usr/bin/env ruby

Array_A = []
myHash = {
                "x1" => "2",
                "x2" => "0",
                "x3" => "1",
                .
                .
                .
                "X350" => "1"
                }

myHash.keys.each do |z|
    Array_A << "This is key " + z
end

puts myHash.values.join("|")                            
puts Array_A.join("|") 

But since the hash is very large, for reading purposes I'd like to put the hash at the end of the script and the each.do loop and puts command first,
something like below.

Is there a way to do this?

Thanks in advance for any help.

Array_A = []

myHash.keys.each do |z|
    Array_A << "This is key " + z
end

puts myHash.values.join("|")                            
puts Array_A.join("|") 

myHash = {
                "x1" => "2",
                "x2" => "0",
                "x3" => "1",
                .
                .
                .
                "X350" => "1"
                }