I have this code that downloads file from ftp server and then it creates that file in path that is set.
string inputfilepath = #"C:\Users\me\Documents\Test";
string ftphost = "ftp_server";
string ftpfilepath = #"/TestDOTNET/text.TXT";
string ftpfullpath = "ftp://" + ftphost + ftpfilepath;
using (WebClient request = new WebClient())
{
request.Proxy = null;
request.Credentials = new NetworkCredential("user", "pass");
byte[] fileData = request.DownloadData(ftpfullpath);
File.SetAttributes(inputfilepath, FileAttributes.Normal);
using (FileStream file = File.Create(inputfilepath)) // this is the line where I get the exception
{
file.Write(fileData, 0, fileData.Length);
file.Close();
}
MessageBox.Show("Download Complete");
}
I tried to create app.manifest and set requestedExcetuion level to requireAdministrator but still got no change.
Thank you for your time
Are you sure the user running the app has write-access to the file system?
You should check that the effective user running the app - which is usually a different user (eg. NETWORK SERVICE user) from yourself - has the appropriate rights.
Check on IIS application pool settings which is the user running the app
Assign appropriate rights to such user on your target folder
You should first test for the Directory Path if it exists or not, if yes, then negate the read-only attribute for that directory. If not, then create directory and then create the test.txt to write in it.
Ex::
string inputdirpath = #"C:\Users\me\Documents\Test";
string inputfilepath = inputdirpath + "\text.TXT";
// Downloading Stuff
if(Directory.Exists(inputdirpath ))
{
var di = new DirectoryInfo("inputfilepath ");
di.Attributes &= ~FileAttributes.ReadOnly;
using (FileStream file = File.Create(inputfilepath))
{
file.Write(fileData, 0, fileData.Length);
file.Close();
}
MessageBox.Show("Download Complete");
}
else
{
// Create Directory
// Set Attributes
// Create file
// Write data
}
Related
This question already has an answer here:
File.Delete the process cannot access the file because it is being used by another process
(1 answer)
Closed 2 years ago.
I need to create small console application to move files into separate folders. Everything works fine, I can copy file, until I try to File.Move or File.Delete file, I catch System.UnauthorizedAccessException. What I've tried
changing folder permission from code
switching from .Net Core to .Net Framework
Manually adding permission to folder by rightclicking->Security->Advance
tried to change Folder's Read-only attribute (it always reverts back to readonly, I can't solve this)
I don't know what else I can try and how to solve this problem. The code I wrote is below
var pngFiles = Directory.GetFiles(#"C:\Users\MSI_PC\Desktop\Test", "*.png",
SearchOption.AllDirectories);
foreach (var pngFile in pngFiles)
{
Console.WriteLine(pngFile);
var fileName = Path.GetFileName(pngFile);
var newFolder = Path.Combine(#"C:\Users\MSI_PC\Desktop\Test",
Path.GetFileNameWithoutExtension(fileName));
Directory.CreateDirectory(newFolder);
var newFileName = Path.Combine(#"C:\Users\MSI_PC\Desktop\Test",
Path.GetFileNameWithoutExtension(fileName), fileName);
File.Copy(pngFile, newFileName, true); //yes, I can use move and have 1 line of code instead of 2. But I need file to be copied, and this line of code works fine
File.Delete(pngFile); // System.UnauthorizedAccessException. File.Move throws the same exception
}
try this code
private void Copy()
{
var pngFiles = Directory.GetFiles(#"C:\Users\Administrator\Desktop", "*.png", SearchOption.AllDirectories);
foreach (var pngFile in pngFiles)
{
Console.WriteLine(pngFile);
var fileName = Path.GetFileName(pngFile);
var newFolder = Path.Combine(#"D:\NewPic\");
Directory.CreateDirectory(newFolder);
string DestPath = newFolder + "\\" + fileName;
byte[] buffer = new byte[2014 * 1024];
using (FileStream source = new FileStream(pngFile, FileMode.Open, FileAccess.Read, FileShare.Delete))
{
using (FileStream dest = new FileStream(DestPath, FileMode.CreateNew, FileAccess.Write, FileShare.Delete))
{
int currentBlockSize = 0;
while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0)
{
dest.Write(buffer, 0, currentBlockSize);
}
dest.Close();
}
source.Close();
}
File.Delete(pngFile); // System.UnauthorizedAccessException. File.Move throws the same exception
}
}
Use the OneDrive SDK to upload files.
At this time, you have to pass the file path, but uploading using the code takes a long time.
Can I upload files even if I pass the temporary file path?
Currently I get the file path after saving the file to the server.
In this case, an issue arises from speed problems.
Is there any way to look at the temporary file path?
public async Task<JObject> UploadLargeFiles(string upn, IFormFile files)
{
var jObject = new JObject();
int fileSize = Convert.ToInt32(files.Length);
var folderName = Path.Combine("wwwroot", "saveLargeFiles");
var pathToSave = Path.Combine(System.IO.Directory.GetCurrentDirectory(), folderName);
var fullPath = "";
if (files.Length > 0)
{
var fileName = files.FileName;
fullPath = Path.Combine(pathToSave, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
files.CopyTo(stream);
}
var filePath = fullPath;
var fileStream = System.IO.File.OpenRead(filePath);
GraphServiceClient client = await MicrosoftGraphClient.GetGraphServiceClient();
var uploadProps = new DriveItemUploadableProperties
{
ODataType = null,
AdditionalData = new Dictionary<string, object>
{
{ "#microsoft.graph.conflictBehavior", "rename" }
}
};
var item = this.SelectUploadFolderID(upn).Result;
var uploadSession = await client.Users[upn].Drive.Items[item].ItemWithPath(files.FileName).CreateUploadSession(uploadProps).Request().PostAsync();
int maxChunkSize = 320 * 1024;
var uploadTask = new LargeFileUploadTask<DriveItem>(uploadSession, fileStream, maxChunkSize);
var response = await uploadTask.UploadAsync();
if (response.UploadSucceeded)
{
return
}
else
{
return null;
}
}
Your server's disk is probably not what makes this slow. By default, uploaded files are stored in a temporary directory, which you can save permanently by using CopyTo(FileStream) like you do.
You can skip this step and call IFormFile.OpenReadStream() to obtain a stream to the temporary file, then pass that to the LargeFileUploadTask.
Point is, it's probably the uploading to OneDrive that takes the largest amount of time. Depending on your setup, you may want to save files into a queue directory (the temp file gets deleted after the request completes), and have a background service read that queue and upload them to OneDrive.
I have some files inside in one .tar.gz archive. These files are on a linux server.How can I read from a specific file inside this archive if I know it's name?
For reading direct from the txt file, I used the following code:
Uri urlFile = new Uri("ftp://" + ServerName + "/%2f" + FilePath + "/" + fileName);
WebClient req = new WebClient() { Credentials=new NetworkCredential("user","psw")};
string result = req.DownloadString(urlFile);
It's possible to read this file without copying the archive on the local machine, something like the code above?
I found a solution. Maybe this can help you guys.
// archivePath="ftp://myLinuxServer.com/%2f/move/files/archive/20170225.tar.gz";
public static string ExtractFileFromArchive(string archivePath, string fileName)
{
string stringFromFile="File not found";
WebClient wc = new WebClient() { Credentials = cred, Proxy= webProxy }; //Create webClient with all necessary settings
using (Stream source = new GZipInputStream(wc.OpenRead(archivePath))) //wc.OpenRead() create one stream with archive tar.gz from our server
{
using (TarInputStream tarStr =new TarInputStream(source)) //TarInputStream is a stream from ICSharpCode.SharpZipLib.Tar library(need install SharpZipLib in nutgets)
{
TarEntry te;
while ((te = tarStr.GetNextEntry())!=null) // Go through all files from archive
{
if (te.Name == fileName)
{
using (Stream fs = new MemoryStream()) //Create a empty stream that we will be fill with file contents.
{
tarStr.CopyEntryContents(fs);
fs.Position = 0; //Move stream position to 0, in order to read from beginning
stringFromFile = new StreamReader(fs).ReadToEnd(); //Convert stream to string
}
break;
}
}
}
}
return stringFromFile;
}
I am trying to read from a folder, and delete a specified file from inside.
I am able to do this one time without any issues.
However after doing it the first time, I am no longer able to Create the new file. The old one is still deleted, but the new file is no longer being created as it should. My question is; From the code provided why would the task work once, but not after that? It's being deleted after the first time but won't re-create.
EDIT:
The issue was in permissions.
I changed the folder security settings to allow reading/writing and I am now able to do it as I wanted.
However, I need it to automatically set the security settings if possible as other users may not know how to do so.
if (Directory.Exists(path1))
{
if (File.Exists(path1 + "\\launchinfo.txt"))
{
File.Delete(path1 + "\\launchinfo.txt");
using (FileStream fs = File.Create(path1 + "\\launchinfo.txt"))
{
Byte[] info = new UTF8Encoding(true).GetBytes("[Connection]\n" + Form1.ipaddress + "\nport=0000\nclient_port=0\n[Details]\n" + Form1.playername);
fs.Write(info, 0, info.Length);
}
}
else
{
using (FileStream fs = File.Create(path1 + "\\launchinfo.txt"))
{
Byte[] info = new UTF8Encoding(true).GetBytes("[Connection]\n" + Form1.ipaddress + "\nport=0000\nclient_port=0\n[Details]\n" + Form1.playername);
fs.Write(info, 0, info.Length);
}
}
}
You've not posted any possible exception you may be running into - if you do have one, please post it.
That being said, it's possible that you're encountering File in use by another process when trying to delete the file - especially if you're calling your function moments after creating a file.
A method to get around this is to check if a process is using the file before you try to delete it.
string fullPath = Path.Combine(path1, "launchinfo.txt");
if (Directory.Exists(path1))
{
if (File.Exists(fullPath))
{
// Call a method to check if the file is in use.
if (IsFileLocked(new FileInfo(fullPath)){
// do something else because you can't delete the file
} else {
File.Delete(fullPath);
}
}
using (FileStream fs = File.Create(fullPath))
{
Byte[] info = new UTF8Encoding(true).GetBytes("[Connection]\n" + Form1.ipaddress + "\nport=0000\nclient_port=0\n[Details]\n" + Form1.playername);
fs.Write(info, 0, info.Length);
}
}
A method to check if the file is in use by another process
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
I have created a TCP server in c# which receives a file from a client and keeps it in the current directory. The code segment which does this is as follows:
using (FileStream fStream = new FileStream(Path.GetFileName(cmdFileName), FileMode.Create))
{
fStream.Write(buffer, 0, buffer.Length);
fStream.Flush();
fStream.Close();
}
Console.WriteLine("File received and saved in " + Environment.CurrentDirectory);
where cmdFileName is the received filename.
Now I have created a folder named "test" inside the current directory using the following code:
string root = Environment.CurrentDirectory;
string folder = Path.Combine(root,"test");
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
I want to keep the received file inside the "test" folder. I need to make change to the following line of my previous code segment:
using (FileStream fStream = new FileStream(Path.GetFileName(cmdFileName), FileMode.Create))
But what change will I have to make?
You are using Path.Combine to get the path of the new test directory--you just need to use it again to find the path of the cmdFileName file inside the test directory:
string cmdFilePath = Path.Combine(folder, Path.GetFileName(cmdFileName));
using (FileStream fStream = new FileStream(cmdFilePath, FileMode.Create))
After this code:
string root = Environment.CurrentDirectory;
string folder = Path.Combine(root,"test");
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
Add another usage of the Path.Combine since you want to attach the path folder to the file cmdFileName:
string fullFilePath = Path.Combine(folder, Path.GetFileName(cmdFileName));
using (FileStream fStream = new FileStream(fullFilePath, FileMode.Create))
{
...
}
Console.WriteLine("File received and saved in " + fullFilePath);
Also you should want to do it inside a try block in order to announce that it succeeded only if it really did:
try
{
using (FileStream fStream = new FileStream(fullFilePath, FileMode.Create)) //Exception accessing the file will prevent the console writing.
{
...
}
Console.WriteLine("File received and saved in " + fullFilePath);
}
catch (...){...Console.WriteLine("Could not write to file " + fullFilePath);...}