Parallel for each loop does not save all files - c#

I writing on an image converter. When I use parallel for each not all images are saved. Is the processing too fast for writing files on disk?
Here is my code:
private void convert()
{
Parallel.ForEach(source.GetFiles("*.tif"),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
file =>
{
fileName = file.Name;
MagickImage image = new MagickImage(sourceFolderPath + "\\" + file);
image.ColorSpace = ColorSpace.XYZ;
image.GammaCorrect(2.4);
image.Write(destinationFolderPath + "\\" + fileName);
});
}
What did I do wrong?

Try disposing the image:
private void convert()
{
Parallel.ForEach(source.GetFiles("*.tif"),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
file =>
{
fileName = file.Name;
using (MagickImage image = new MagickImage(sourceFolderPath + "\\" + file))
{
image.ColorSpace = ColorSpace.XYZ;
image.GammaCorrect(2.4);
image.Write(destinationFolderPath + "\\" + fileName);
}
});
}

Related

Read zip for photos with multiple photo file extensions using C#

I've created a method that reads .jpg files and displays them on my screen without extracting.
The var looks like this
var imageName = content.contentid + ".jpg";
content.contentid is too id number of the number + .jpg
But now I want that if there is, for example, a png or jfif file in the zip that it also just shows it.
How do I handle this in this method?
This is my code so far
private void getImage()
{
try
{
var folderName = "protocol-" + _protocol.id + "-" + _protocol.versionnr + ".zip";
var extractPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var zipPath = $"{extractPath}" + "/" + $"{folderName}";
var currentIndex = getCurrentIndex();
var content = _protocol.contents[currentIndex];
List<string> allowedExtensions = new List<string>() { "jpg", "png", "jfif" };
using (var archive = ZipFile.OpenRead(zipPath))
{
foreach (var pictureEntry in archive.Entries)
if (Path.GetFileNameWithoutExtension(pictureEntry.Name).Equals(content.contentid) && allowedExtensions.Contains(Path.GetExtension(pictureEntry.Name)))
{
byte[] buffer;
var length = pictureEntry.Length;
buffer = new byte[length];
pictureEntry.Open().Read(buffer, 0, (int)length);
myImage.Source = ImageSource.FromStream(() => new MemoryStream(buffer));
}
}
}
catch (Exception)
{
}
}
Well you can try this approach:
First define a List of extensions that you want to check against:
List<string> allowedExtensions = new List<string>() {"jpg", "png", "jfif" };
then change your if (pictureEntry.Name == imageName) for
if (Path.GetFileNameWithoutExtension(pictureEntry.Name) == content.contentid &&
allowedExtensions.Contains(Path.GetExtension(pictureEntry.Name)))
Also this line var imageName = content.contentid + ".jpg"; is innecesary as imageName didn't be used:

Downloading a directory using SSH.NET SFTP in C#

I am using Renci.SSH and C# to connect to my Unix server from a Windows machine. My code works as expected when the directory contents are only files, but if the directory contains a folder, I get this
Renci.SshNet.Common.SshException: 'Failure'
This is my code, how can I update this to also download a directory (if exists)
private static void DownloadFile(string arc, string username, string password)
{
string fullpath;
string fp;
var options = new ProgressBarOptions
{
ProgressCharacter = '.',
ProgressBarOnBottom = true
};
using (var sftp = new SftpClient(Host, username, password))
{
sftp.Connect();
fp = RemoteDir + "/" + arc;
if (sftp.Exists(fp))
fullpath = fp;
else
fullpath = SecondaryRemoteDir + d + "/" + arc;
if (sftp.Exists(fullpath))
{
var files = sftp.ListDirectory(fullpath);
foreach (var file in files)
{
if (file.Name.ToLower().Substring(0, 1) != ".")
{
Console.WriteLine("Downloading file from the server...");
Console.WriteLine();
using (var pbar = new ProgressBar(100, "Downloading " + file.Name + "....", options))
{
SftpFileAttributes att = sftp.GetAttributes(fullpath + "/" + file.Name);
var fileSize = att.Size;
var ms = new MemoryStream();
IAsyncResult asyncr = sftp.BeginDownloadFile(fullpath + "/" + file.Name, ms);
SftpDownloadAsyncResult sftpAsyncr = (SftpDownloadAsyncResult)asyncr;
int lastpct = 0;
while (!sftpAsyncr.IsCompleted)
{
int pct = (int)((long)sftpAsyncr.DownloadedBytes / fileSize) * 100;
if (pct > lastpct)
for (int i = 1; i < pct - lastpct; i++)
pbar.Tick();
}
sftp.EndDownloadFile(asyncr);
Console.WriteLine("Writing File to disk...");
Console.WriteLine();
string localFilePath = "C:\" + file.Name;
var fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write);
ms.WriteTo(fs);
fs.Close();
ms.Close();
}
}
}
}
else
{
Console.WriteLine("The arc " + arc + " does not exist");
Console.WriteLine();
Console.WriteLine("Please press any key to close this window");
Console.ReadKey();
}
}
}
BeginDownloadFile downloads a file. You cannot use it to download a folder. For that you need to download contained files one by one.
The following example uses synchronous download (DownloadFile instead of BeginDownloadFile) for simplicity. After all, you are synchronously waiting for asynchronous download to complete anyway. To implement a progress bar with synchronous download, see Displaying progress of file download in a ProgressBar with SSH.NET.
public static void DownloadDirectory(
SftpClient sftpClient, string sourceRemotePath, string destLocalPath)
{
Directory.CreateDirectory(destLocalPath);
IEnumerable<SftpFile> files = sftpClient.ListDirectory(sourceRemotePath);
foreach (SftpFile file in files)
{
if ((file.Name != ".") && (file.Name != ".."))
{
string sourceFilePath = sourceRemotePath + "/" + file.Name;
string destFilePath = Path.Combine(destLocalPath, file.Name);
if (file.IsDirectory)
{
DownloadDirectory(sftpClient, sourceFilePath, destFilePath);
}
else
{
using (Stream fileStream = File.Create(destFilePath))
{
sftpClient.DownloadFile(sourceFilePath, fileStream);
}
}
}
}
}

how to copy file from my app Using FileSavePicker UWP

I want copy file in my app to a folder with FileSavePicker. My Code:
var fileSavePicker = new FileSavePicker();
fileSavePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
var filedb = new[] { ".db" };
fileSavePicker.FileTypeChoices.Add("DB", filedb);
fileSavePicker.SuggestedFileName = "BACKUPDB" + System.DateTime.Now.Day + "-" + System.DateTime.Now.Month + "-" + System.DateTime.Now.Year;
//var pathDB = Path.Combine(ApplicationData.Current.LocalFolder.Path, "file.db");
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("file.db");
StorageFile localfile = await fileSavePicker.PickSaveFileAsync();
fileSavePicker.SuggestedSaveFile = file;
if (file != null)
{
Debug.WriteLine("file Exists!!");
var fileToSave = await fileSavePicker.PickSaveFileAsync();
....
but my saved file has size 0.
I found how to save text files but my file not is text.
You can use CopyAndReplaceAsync method to copy your local file to the chosen file.
var fileSavePicker = new Windows.Storage.Pickers.FileSavePicker();
fileSavePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
var filedb = new[] { ".db" };
fileSavePicker.FileTypeChoices.Add("DB", filedb);
fileSavePicker.SuggestedFileName = "BACKUPDB" + System.DateTime.Now.Day + "-" + System.DateTime.Now.Month + "-" + System.DateTime.Now.Year;
//var pathDB = Path.Combine(ApplicationData.Current.LocalFolder.Path, "file.db");
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("file.db");
StorageFile localfile = await fileSavePicker.PickSaveFileAsync();
if (file != null)
{
Debug.WriteLine("file Exists!!");
await file.CopyAndReplaceAsync(localfile);
}
}
catch(Exception ex)
{
Debug.WriteLine(ex);
}

how to share image copying from one folder to another folder Process in c#

When we are copying images in one folder to another folder, images are going to copy one by one, then it takes more time when thousands's of images are copying, Is there any Possibility to copy Multiple images at a time? "This is My code"
int avilableCharts = 0;
int unavialableCharts = 0;
string chartid;
int count = 0;
StreamReader rd = new StreamReader(txtFileName.Text);
StreamWriter tw = new StreamWriter("C:\\LogFiles\\SucessfullyMovedImages.txt");
StreamWriter tw1 = new StreamWriter("C:\\LogFiles\\UnavailableImages.txt");
DirectoryInfo dirinfo = new DirectoryInfo(txtSourceFolder.Text);
FileInfo[] file = dirinfo.GetFiles("*.pdf");
while (!rd.EndOfStream)
{
chartid = rd.ReadLine() + ".pdf";
count = count + 1;
worker.ReportProgress(count);
string FName = string.Empty;
if (File.Exists(txtSourceFolder.Text + chartid))
{
File.Copy(txtSourceFolder.Text + chartid , txtDestinationFolder.Text + chartid );
avilableCharts = avilableCharts + 1;
tw.WriteLine(chartid);
}
else
{
unavialableCharts = unavialableCharts + 1;
tw1.WriteLine(chartid);
}
}
tw.Close();
tw1.Close();
MessageBox.Show("Successfully Copied Images are :" + avilableCharts);
MessageBox.Show("Total Unavilable Images are : " + unavialableCharts);
use below code :
public class SimpleFileMove
{
static void Main()
{
string sourceFile = #"C:\Users\Public\public\test.txt";
string destinationFile = #"C:\Users\Public\private\test.txt";
// To move a file or folder to a new location:
System.IO.File.Move(sourceFile, destinationFile);
// To move an entire directory. To programmatically modify or combine
// path strings, use the System.IO.Path class.
System.IO.Directory.Move(#"C:\Users\Public\public\test\", #"C:\Users\Public\private");
}
}

MyThread.Join() blocks the whole application. Why?

I want to download a file from a FTP server in the other Thread. The problem is, this thread causes that my application is freezed. Here You have the code, what am I doing wrong? Any help will by grateful :)
(Of course I want to stop looping until the thread 'ReadBytesThread' terminates.)
I make a new thread:
DownloadThread = new Thread(new ThreadStart(DownloadFiles));
DownloadThread.Start();
private void DownloadFiles()
{
if (DownloadListView.InvokeRequired)
{
MyDownloadDeleg = new DownloadDelegate(Download);
DownloadListView.Invoke(MyDownloadDeleg);
}
}
private void Download()
{
foreach (DownloadingFile df in DownloadingFileList)
{
if (df.Size != "<DIR>") //don't download a directory
{
ReadBytesThread = new Thread(() => {
FileData = sendPassiveFTPcmd("RETR " + df.Path + "/" + df.Name + "\r\n");
FileStream fs = new FileStream(#"C:\Downloads\" + df.Name, FileMode.Append);
fs.Write(FileData, 0, FileData.Length);
fs.Close();
});
ReadBytesThread.Start();
(here->) ReadBytesThread.Join();
MessageBox.Show("Downloaded");
}
}
}
you're calling DownloadFiles in a secondary thread but this function call Download() in the UI thread via DownloadListView.Invoke --> your application freezes because the download is done in the main thread.
you can try this approach:
DownloadThread = new Thread(new ThreadStart(DownloadFiles));
DownloadThread.Start();
private void DownloadFiles()
{
foreach (DownloadingFile df in DownloadingFileList)
{
if (df.Size != "<DIR>") //don't download a directory
{
ReadBytesThread = new Thread(() => {
FileData = sendPassiveFTPcmd("RETR " + df.Path + "/" + df.Name + "\r\n");
FileStream fs = new FileStream(#"C:\Downloads\" + df.Name,
FileMode.Append);
fs.Write(FileData, 0, FileData.Length);
fs.Close();
});
ReadBytesThread.Start();
ReadBytesThread.Join();
if (DownloadListView.InvokeRequired)
{
DownloadListView.Invoke(new MethodInvoker(delegate(){
MessageBox.Show("Downloaded");
}));
}
}
}
}

Categories

Resources