Task.Run still freezing UI - c#

So, i'm trying to convert a large byte array into it's base64 encoded variant. But no matter what i try, it seems to freeze up my UI every time it runs.
This is what i've got currently:
private async void TxtOutput_DragDrop(object sender, DragEventArgs e)
{
string outputText = String.Empty;
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] path = (string[])e.Data.GetData(DataFormats.FileDrop);
byte[] fileBytes = File.ReadAllBytes(path[0]);
txtOutput.Text = await Task.Run(() => {return Convert.ToBase64String(fileBytes);});
_ = fileBytes;
_ = path;
}
}
So, the line that freezes everything up is:
txtOutput.Text = await Task.Run(() => {return Convert.ToBase64String(fileBytes);});

File.ReadAllBytes(path[0])
Could be a bottle neck you can use async operation for read files
Here is an example how to read file async
public async Task ProcessReadAsync()
{
string filePath = #"temp2.txt";
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
Debug.WriteLine(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}

Right, so it turns out that my problem was using a textbox for writing the string to instead of a richtextbox. This fixed my problem. Thanks for your answers.

Related

Convert Zip File to byte[] and byte[] to zip file

I try to convert zip file to byte[] and write it to a text file.
int BufferSize=65536;
private void button1_Click(object sender, EventArgs e)
{
DialogResult re = openFileDialog1.ShowDialog();
if (re == DialogResult.OK)
{
string fileName = openFileDialog1.FileName;
try
{
byte[] bytes = File.ReadAllBytes(fileName);
File.WriteAllBytes(#"F:\Info.txt", bytes);
}
catch (Exception) { }
}
}
Then I try to convert those byte to zip file. But I can't do it.
My code is here:
private void button2_Click(object sender, EventArgs e)
{
DialogResult re = openFileDialog1.ShowDialog();
if (re == DialogResult.OK)
{
string fileName = openFileDialog1.FileName;
try
{
byte[] bytes = File.ReadAllBytes(fileName);
using (var mstrim = new MemoryStream(bytes))
{
using (var inStream = new GZipStream(mstrim, CompressionMode.Compress))
{
using (var outStream = File.Create("Tax.Zip"))
{
var buffer = new byte[BufferSize];
int readBytes;
while ((readBytes = inStream.Read(buffer, 0, BufferSize)) != 0)
{
outStream.Write(buffer, 0, readBytes);
}
}
}
}
}
catch (Exception) { }
}
}
Error:File Mode not valid.
What File Mode is needed and how can I accomplish what I described?
Just try this.
byte[] data = File.ReadAllBytes("D:\\z.7z");
File.WriteAllBytes("D:\\t.txt", data); // Requires System.IO
byte[] newdata = File.ReadAllBytes("D:\\t.txt");
File.WriteAllBytes("D:\\a.7z", newdata); // Requires System.IO
Try this,
private void button1_Click(object sender, EventArgs e)
{
byte[] arr;
MemoryStream ms = new MemoryStream();
arr = File.ReadAllBytes("C:\\asik.zip");
File.WriteAllBytes(#"D:\\asik.txt", arr);
ms.Close();
FileStream stream = File.OpenRead(#"D:\\asik.txt");
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
stream.Close();
MemoryStream ms1 = new MemoryStream(fileBytes);
CreateToMemoryStream(ms1, #"D:\\asik.zip");
ms1.Close();
}
public void CreateToMemoryStream(MemoryStream memStreamIn, string zipEntryName)
{
MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
ZipEntry newEntry = new ZipEntry(zipEntryName);
newEntry.DateTime = DateTime.Now;
zipStream.PutNextEntry(newEntry);
StreamUtils.Copy(memStreamIn, zipStream, new byte[4096]);
zipStream.CloseEntry();
zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.
zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream.
//outputMemStream.Position = 0;
//return outputMemStream;
//// Alternative outputs:
//// ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory.
//byte[] byteArrayOut = outputMemStream.ToArray();
//// GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.
//byte[] byteArrayOut2 = outputMemStream.GetBuffer();
//long len = outputMemStream.Length;
}
You're using GZipStream, which is used for GZip files, not (PK-)Zip files. This isn't going to work, obviously. Try the ZipFile class instead (though sadly, it doesn't work on streams, just files).
Apart from simply being a different file format, the big difference is that GZip is for compression only, while Zip is also an archive (that is, it can contain multiple files).
public class BytesVal {
public static void main(String[] args) throws IOException, MoreZipException {
// TODO Auto-generated method stub
File file = new File("F:\\ssd\\doc\\");
System.out.println("Byte inside the Zip file is" + BytesVal.getAllBytes(file));
}
public static byte[] getAllBytes(File folderName) throws IOException, MoreZipException {
String[] sourceFiles = null;
if (folderName.isDirectory()) {
sourceFiles = folderName.list();
if (sourceFiles.length > 1) {
throw new MoreZipException(sourceFiles.length);
}
}
byte[] bytes = null;
Path filePath = Paths.get("F:/ssd/doc/" + sourceFiles[0]);
bytes = Files.readAllBytes(filePath);
return bytes;
}
}

Async Task outputting in chinese characters instead of readable text

I am attempting to search files for specific text using an async Task. The output I receive is in chinese characters instead of what is actually in the text file I am parsing. Here is the code:
public async void ProcessRead(string fileLocation)
{
string filePath = fileLocation;
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
Debug.WriteLine(text);
if (text.Contains(inputContentPattern))
{
addToDataGrid(Path.GetFileName(filePath), filePath, "");
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
findButton.Enabled = true;
cancelFindButton.Enabled = false;
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
You are reading the file using Unicode encoding (in an incorrect way). Find out what encoding the file actually has and use that encoding. Simply use File.ReadAllText and delete ReadTextAsync.
Async IO brings you zero performance benefits here so just don't do it. If this is a UI app use await Task.Run(() => File.ReadAllText(...)).

C# using LoadFile or ReadallLines on RichTextBox

I have a problem on a few systems that when we are trying to load the RichTextBox the program becomes unresponsive, we cannot do anything and will have to kill it via Taskmanager.
its working on most systems but a few systems located in a different country there seems to be problem.
we have tried something as simple as :
private void testing4()
{
richTextBox1.LoadFile(#"C:\testing.logs", RichTextBoxStreamType.PlainText);
}
If we decide to use a normal TextBox it appears to be working using .net 4.5, but it still becomes unresponsive. Any ideas?
This may help you:
foreach(var line in File.ReadLines(#"C:\testing.logs"))
{
richTextBox1.AppendText(line+Environment.NewLine);
}
Since you are using framework 4.5, you can do it async, as in MSDN example:
public async void ReadFile()
{
string filePath = #"C:\testing.logs";
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
richTextBox1.AppendText(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
Source: Using Async for File Access

How to check whether my C# code is reading the file in asynchronous mode?

public void fileReader()
{
Stream stream = new FileStream(filename, FileMode.Open , FileAccess.Read , FileShare.None, 30, true);
byte[] Buffer = new byte[30];
while (stream.Read(Buffer, 0, 30) > 0)
{
label1.text=Encoding.UTF8.GetString(Buffer);
Thread.Sleep(1000);
}
stream.Dispose();
}
THIS IS MY C# CODE TO READ 30 BYTES OF DATA AT A TIME FROM A FILE. I've created the Stream with FileStream constructor having useAsync=true. Here stream.Read method is used.
Is this read operation working in ASYNCHRNOUS mode?
How to check this?
Another problem is that Encoding.UTF8.GetString(Buffer); gives white spaces as '□' character... y?
Is there any other way to make a 1 second delay other than Thread.Sleep(1000); ?
It doesn't since you are using the syncronous Readmethod
if you wish to read it asyncronous you would have to use the BeginRead method
Below is an example on the usage of BeginRead from MSDN
private void ReadStreamAsyncImpl(Stream stream)
{
chunk = new byte[chunkSize];
stream.BeginRead(chunk,
0,
chunkSize,
new AsyncCallback(BeginReadCallback),
stream);
}
private void BeginReadCallback(IAsyncResult ar)
{
Stream stream = ar.AsyncState as Stream;
int bytesRead = stream.EndRead(ar);
StreamContentsAsString += StreamEncoding.GetString(chunk, 0, bytesRead);
if (bytesRead < chunkSize) {
// Finished
isOperationInProgress = false;
stream.Close();
if (null != ReadStreamCompleted) {
ReadStreamCompleted(this, new EventArgs());
}
} else {
ReadStreamAsyncImpl(stream);
}
}
That said you should probably use a StreamReader to read the characters of the stream instead of converting them yourself.
if you are using .NET 4.5 you can use ReadAsync as below (again from [MSDN][2])
private async void Button_Click(object sender, RoutedEventArgs e)
{
UnicodeEncoding uniencoding = new UnicodeEncoding();
string filename = #"c:\Users\exampleuser\Documents\userinputlog.txt";
byte[] result;
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
result = new byte[SourceStream.Length];
await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);
}
UserInput.Text = uniencoding.GetString(result);
}
Reading your file like that seems to be causing you a lot of problems without solving anything. I do not see the point of reading 30 bytes at a time and then decode the result. You might end up decoding the last character wrong.
I recommend that you do something like this:
using(StreamReader reader = new StreamReader(filename, Encoding.UTF8))
{
while(!reader.EndOfStream)
{
String result = await reader.ReadLineAsync();
label1.Text = result;
}
}
But maybe a BackgroundWorker is much easier to use, sending the line to the UI using the progress callback.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
using(StreamReader reader = new StreamReader(e.Argument as String, Encoding.UTF8))
{
while(!reader.EndOfStream)
{
String line = reader.ReadLine();
backgroundWorker.ReportProgress(0, line);
Thread.Sleep(1000);
if (backgroundWorker.CancellationPending)
return;
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = e.UserState as String;
}

How to Zip a folder with encrypt password using ICSharplib

How to Zip a folder using ICSharplib.
Is there any way I can add a encrypt password while zipping it ?
There is no option that I can use any other dll. Have to use only ICSharplib.
Currently I am using this code block
private static void CompressFiles(string folderPath) {
string zipOutput = #"C:\temp\myoutput.zip";
try {
using (ZipOutputStream zs = new ZipOutputStream(File.Create(zipOutput))) {
zs.SetLevel(9); // 0-9 (9 being best compression)
foreach (string file in Directory.GetFiles(folderPath)) {
ZipEntry entry = new ZipEntry(Path.GetFileName(file));
entry.DateTime = DateTime.Now;
using (FileStream fs = File.OpenRead(file)) {
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
entry.Size = buffer.Length; // This is very important
zs.PutNextEntry(entry);
zs.Write(buffer, 0, buffer.Length);
}
}
zs.Finish();
zs.Close();
}
}
catch { throw; }
}
It can zip all the files in the folder.
But What I want is to zip the whole folder.
Like the folders in side that folder also be included in the zip file .
Thanks in advance
Use the FastZip object.
ICSharpCode.SharpZipLib.Zip.FastZip z = new ICSharpCode.SharpZipLib.Zip.FastZip();
z.CreateEmptyDirectories = true;
z.CreateZip("F:\\ZipTest.zip", "F:\\ZipTest\\", true, "");
if (File.Exists("F:\\ZipTest.zip"))
Console.WriteLine("Done");
else
Console.WriteLine("Failed");
I use following code:
public static bool ZipIt(string sourcePath, string destinationPath)
{
List<string> ListOfFiles = GetListOfFiles(sourcePath);
try
{
string OutPath = destinationPath + ".zip";
int TrimLength = (Directory.GetParent(sourcePath)).ToString().Length;
TrimLength += 1;
//remove '\'
FileStream ostream;
byte[] obuffer;
ZipOutputStream oZipStream = new ZipOutputStream(System.IO.File.Create(OutPath));
oZipStream.Password = EncodePassword("Password");
oZipStream.SetLevel(9);
// 9 = maximum compression level
ZipEntry oZipEntry;
foreach (string Fil in ListOfFiles.ToArray()) // for each file, generate a zipentry
{
oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));
oZipStream.PutNextEntry(oZipEntry);
if (!Fil.EndsWith(#"/")) // if a file ends with '/' its a directory
{
ostream = File.OpenRead(Fil);
obuffer = new byte[ostream.Length];
ostream.Read(obuffer, 0, obuffer.Length);
oZipStream.Write(obuffer, 0, obuffer.Length);
ostream.Close();
}
}
oZipStream.Finish();
oZipStream.Close();
return true;
}
catch (Exception ex)
{
return false;
}
}
public static string EncodePassword(string originalPassword)
{
Byte[] encodedBytes;
encodedBytes = ASCIIEncoding.Default.GetBytes(originalPassword);
return BitConverter.ToString(encodedBytes);
}

Categories