File.Move making a copy of file - c#

I have some code where I'm attempting to create a temporary file to be used as a zip file.
string tempPath = Path.GetTempFileName();
string targetPath =
string.Concat(Path.GetTempPath(),"//",Path.GetFileNameWithoutExtension(tempPath),".zip");
File.Move(tempPath, targetPath);
However a new file is being created instead of moving (renaming) the temp file.
I'm definitely confused...
Kevin

I think this is what you're looking for:
FileInfo.MoveTo()
var newFiles = System.IO.Directory.GetFiles(updateLocation).Select(file => new FileInfo(file));
var workingDirectory = Environment.CurrentDirectory;
var existingFiles = System.IO.Directory.GetFiles(workingDirectory).Select(file => new FileInfo(file));
newFiles.ToList().ForEach(newFile =>
{
var matchedFile = existingFiles.ToList().Find(delegate(FileInfo file) { return file.Name == newFile.Name; });
if(matchedFile != null)
{
if(newFile.LastWriteTimeUtc != matchedFile.LastWriteTimeUtc)
{
if(!Directory.Exists(TEMP_DIRECTORY_NAME))
Directory.CreateDirectory(TEMP_DIRECTORY_NAME);
matchedFile.MoveTo(Path.Combine(TEMP_DIRECTORY_NAME, matchedFile.Name));
newFile.CopyTo(Path.Combine(workingDirectory, newFile.Name));
}
}
else
newFile.CopyTo(Path.Combine(workingDirectory, newFile.Name));
});'

That's expected behavior. If you want the old file deleted, you need to explicitly do that.

Your code works for me.
Path.GetTempFileName()
will create a new 0 byte temporary file in your machines %TEMP% directory. After the File.Move line is run the temp file is renamed with a .zip extension.
After this you can now use the file:
using (var writeStream = new FileStream(targetPath, FileMode.Open, FileAccess.ReadWrite))
{
// CODE HERE
}

Related

Unable to move a file once I have read and appended data to a new file c#

I have a foreach loop that is appending data from 1 file (source) to another (destination).
Once the file has been appended with all data I want to move the original source file. When debugging im getting the error "Exception thrown: 'System.IO.IOException' in System.IO.FileSystem.dll"
Im assuming this is because the file is locked. How can I dispose this so I can move the file.
var stringwrite = new[] { prefix, prefix2 };
foreach (string line in File.ReadLines(currentFile))
{
var lastOne = line.Split(';').Last();
if (!stringwrite.Any(stringwrite => lastOne.Contains(stringwrite)))
continue;
//write lines found to new file
File.AppendAllText(todestination, line + Environment.NewLine);
}
//move original file to new directory
try
{
File.Move(currentFile, completeddestination);
break;
}
catch (Exception ex)
{
MessageBox.Show("Issue Moving File");
}
As you are reading the source file to the end and writing to the destination depending on a condition, it would make sense to keep both input and output streams open until the end of read/write operations. Note, that File.ReadLines will open the source file, read the contents, and then close it. Also, File.AppendAllText will open the destination file, append the contents, and then close the file. Such an approach is inefficient. I think, your task could be properly implemented using file streams. Please find the example below:
static void Main()
{
var sourcePath = "C:\\PathToSource";
var destinationPath = "C:\\PathToDestination";
var completedDestinationPath = "C:\\PathToCompletedDestination";
var prefixes = new[] { "some-prefix", "some-other-prefix" };
foreach (var source in EnumerateDataFiles(sourcePath))
{
// This assumes that files in source and destination and completed
// dectination directories have the same file name but different paths.
// If you use another convention for your data, please adjust it here
var destination = GetDestinationFilePath(source, destinationPath);
var completedDestination = GetDestinationFilePath(source, completedDestinationPath);
try
{
AppendData(
source,
destination,
line =>
{
var lastEntry = line.Split(';').Last();
return prefixes.Any(prefix => lastEntry.Contains(prefix));
});
File.Move(source, completedDestination);
}
catch (Exception ex)
{
Console.WriteLine($"Issue Moving File: {ex.Message}");
}
}
}
static IEnumerable<string> EnumerateDataFiles(string path)
{
// Change *.dat to the extension (e.g., *.txt) you use for your data files,
// or to *.* to include all files from the directory
return Directory.EnumerateFiles(path, "*.dat", SearchOption.AllDirectories);
}
static string GetDestinationFilePath(string sourceFileName, string destinationPath)
{
// This will return a file path to the file with the same name as the source
// but located in the destination directory
return Path.Combine(destinationPath, Path.GetFileName(sourceFileName));
}
static void AppendData(string source, string destination, Func<string, bool> linePredicate)
{
using (var inputStream = new FileStream(source, FileMode.Open, FileAccess.Read))
using (var inputReader = new StreamReader(inputStream))
using (var outputStream = new FileStream(destination, FileMode.OpenOrCreate, FileAccess.Write))
using (var outputWriter = new StreamWriter(outputStream))
{
while (inputReader.ReadLine() is string inputLine)
{
if (!linePredicate(inputLine))
continue;
outputWriter.WriteLine(inputLine);
}
}
}
In the example provided, I assumed that you have the same file name but different paths for source, destination, and completed destination file paths. If you use a different naming mechanism, please follow comments to adjust it accordingly.

How to display image angular from .net core API and database

I would like to display a picture whose path it stores in the database
this is how it transfers the image file to the database.
public string UploadImage(IFormFile file)
{
if (file == null) throw new Exception("Pusty plik");
if (file.Length == 0)
{
throw new Exception("Pusty plik");
}
if (!ACCEPTED_FILE_TYPES.Any(s => s == Path.GetExtension(file.FileName).ToLower())) throw new Exception("Zły typ pliku");
if (string.IsNullOrWhiteSpace(host.WebRootPath))
{
host.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
var uploadFilesPath = Path.Combine(host.WebRootPath, "images");
if (!Directory.Exists(uploadFilesPath))
Directory.CreateDirectory(uploadFilesPath);
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
var filePath = Path.Combine(uploadFilesPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
file.CopyToAsync(stream);
}
var path = Path.Combine(Directory.GetCurrentDirectory(), #"/wwwroot/images/", fileName);
return path;
}
here stores files:
https://zapodaj.net/a8829a7a3a90b.png.html
In your sample code I do not see path returning from database.
Also from security point of view it would be bad practice to return /wwwroot/images/ in response. You can create a folder on shared location and return shared location path.
Seems you question and same code isn't aligning.

Unzip Files With Sub-directories To Root Folder

I need some help.
I just have this code right now. This code is working, but it's not enough.
My code;
DirectoryInfo dirFile = new DirectoryInfo(currentDir);
FileInfo[] infoFile = dirFile.GetFiles("*.zip", SearchOption.AllDirectories);
foreach (FileInfo currentFile in infoFile)
{
using (ZipFile zipFile = ZipFile.Read(currentFile.FullName))
{
zipFile.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(unZipFiles_ExtractProgressChanged);
foreach (ZipEntry currentZip in zipFile)
{ currentZip.Extract(currentFile.DirectoryName, ExtractExistingFileAction.OverwriteSilently); }
}
currentCount = increaseCount + 1; increaseCount = currentCount;
if (downloadType == 1) { bar2SetProgress((ulong)currentCount, (ulong)totalCount); }
lblFileName.Text = currentFile.Name;
}
I want to extract all zip files to Application.StartupPath folder from _ZipFiles folder with all subdirectories.
Here is one example;
I have one zip folder. Name: _ZipFolder
Before the unzip process;
Application.StartupPath\_ZipFiles\startProgram.zip
Application.StartupPath\_ZipFiles\updateProgram.zip
Application.StartupPath\_ZipFiles\Pack\testDownload.zip
Application.StartupPath\_ZipFiles\Pack\Version\repo2.zip
Application.StartupPath\_ZipFiles\Pack\Version\newClass.zip
Application.StartupPath\_ZipFiles\Ack\Library\argSetup.zip
Application.StartupPath\_ZipFiles\Ack\learnMachine.zip
Application.StartupPath\_ZipFiles\Code\zipVersion4.zip
After the unzip process (I exactly want to this extract);
Application.StartupPath\startProgram.exe
Application.StartupPath\updateProgram.exe
Application.StartupPath\Pack\testDownload.exe
Application.StartupPath\Pack\Version\repo2.cs
Application.StartupPath\Pack\Version\newClass.cs
Application.StartupPath\Ack\Library\argSetup.exe
Application.StartupPath\Ack\learnMachine.pdf
Application.StartupPath\Code\zipVersion4.exe
All files needs move to Application.StartupPath from _ZipFiles folder with subdirectories.
How to make this? Please help me.
I hope you understand what I want. I'm sorry for my bad English.
Remove the zip folder name from the current file directory name when extracting
Based on current example where you have _ZipFiles folder
DirectoryInfo dirFile = new DirectoryInfo(currentDir);
FileInfo[] infoFile = dirFile.GetFiles("*.zip", SearchOption.AllDirectories);
var zipFolderName = #"\_ZipFiles";
foreach (FileInfo currentFile in infoFile) {
using (ZipFile zipFile = ZipFile.Read(currentFile.FullName)) {
zipFile.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(unZipFiles_ExtractProgressChanged);
var destination = currentFile.DirectoryName.Replace(zipFolderName, "");
foreach (ZipEntry currentZip in zipFile) {
currentZip.Extract(destination, ExtractExistingFileAction.OverwriteSilently);
}
}
currentCount = increaseCount + 1; increaseCount = currentCount;
if (downloadType == 1) { bar2SetProgress((ulong)currentCount, (ulong)totalCount); }
lblFileName.Text = currentFile.Name;
}
If I understood you correctly, you want to extract all files to Application.StartupPath directory instead in subfolders.
Try to change:
currentZip.Extract(currentFile.DirectoryName, ExtractExistingFileAction.OverwriteSilently);
to
currentZip.Extract(Application.StartupPath, ExtractExistingFileAction.OverwriteSilently);
If Application.StartupPath isn't suitable, then maybe use AppDomain.CurrentDomain.BaseDirectory

C# could not find file 'filepath'

I'm getting the 'cannot be found' error although the file does exist and the path is right. I have tried AudiosInfo.txt.txt and it does not work.
FileStream f = new FileStream("AudiosInfo.txt", FileMode.Open);
StreamReader s = new StreamReader(f);
string l=s.ReadLine();
MessageBox.Show(l);
When you are using,
FileStream f = new FileStream("AudiosInfo.txt", FileMode.Open);
you have to ensure that, AudiosInfo.txt file must be stored in your solution's \bin\Debug folder.
Otherwise you have to give the full path.
This is how you can find the full path: right click on the AudiosInfo.txt file, click on properties, click on the details tab and take a look at the folder path.
Might need to use to find the the path
string filePath = #"C:\MyDir\MySubDir\myfile.ext";
string directoryName;
int i = 0;
while (filePath != null)
{
directoryName = Path.GetDirectoryName(filePath);
Console.WriteLine("GetDirectoryName('{0}') returns '{1}'",
filePath, directoryName);
filePath = directoryName;
if (i == 1)
{
filePath = directoryName + #"\"; // this will preserve the previous path
}
i++;
}
/*

File Still Locked Despite putting StreamReader in Using

My program goes through all files in a folder, reads them, and without altering their information moves them to another location under a different name. However I cannot use the File.Move method because I get the following IOException:
The process cannot access the file because it is being used by another
process.
This is how I am reading the file and adding all its lines to a List<string>:
List<string> lines = null;
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var sr = new StreamReader(fs, Encoding.Default))
{
lines = new List<string>();
while (!sr.EndOfStream)
lines.Add(sr.ReadLine());
}
And this is the function with which I move the file:
public static bool ArchiveFile(string filePath, string archiveFolderLocation)
{
if (!Directory.Exists(archiveFolderLocation))
Directory.CreateDirectory(archiveFolderLocation);
try
{
string timestamp = string.Format("{0:yyyy-MM-dd HHmmss}", DateTime.Now);
string newFileName = Path.GetFileNameWithoutExtension(filePath) + " " + timestamp;
string destination = string.Format("{0}\\{1}{2}", archiveFolderLocation, newFileName, Path.GetExtension(filePath));
File.Move(filePath, destination);
return true;
}
catch (Exception ex)
{
return false;
}
}
I thought using the using statement is supposed to garbage-collect and release the file after being used. How can I release the file so I can move it and why my file stays locked?
Solved:
Got it. Somewhere between these two calls I was opening a TextReaderobject without disposing it.
I thought using the using statement is supposed to garbage-collect and
release the file after being used. How can I release the file so I can
move it and why my file stays locked?
Not really. Using statement is nothing but :
try { var resource = new SomeResource(); }
finally { resource.Dispose(); // which is not GC.Collect(); }
It works fine so it looks like your file is opened from some other place in your code...
P.S.
By the way you can just do:
List<string> lines = File.ReadAllLines().ToList();
You could use:
string dpath = "D:\\Destination\\";
string spath = "D:\\Source";
string[] flist = Directory.GetFiles(spath);
foreach (string item in flist)
{
File.Move(item, dpath + new FileInfo(item).Name);
}
Replace D:\\Source & D:\\Destination\\ with the required source and destination paths, respectively.

Categories