I've created a backup and restore procedure for my application. When the backup is run, it will create a .zip file of the SQLite database in the same directory as the database.
When restoring the database, it will rename the database, changing it from EPOSDatabase.db3 to tempEPOS.db3
Then, it takes the selected file and extracts it to the same location, under the name EPOSDatabase.db3, before deleting the renamed temporary database.
string dbPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
if (File.Exists(dbPath + "/tempEPOS.db3"))
{
File.Delete(dbPath + "/tempEPOS.db3");
};
File.Move(dbPath + "/EPOSDatabase.db3", dbPath + "/tempEPOS.db3");
ZipFile.ExtractToDirectory(dbPath + "/" + fileToRestore, dbPath + "/EPOSDatabase.db3");
File.Delete(dbPath + "/tempEPOS.db3");
My issue is that when I then have code that opens the connection, for example when I open the system settings page after the restore has been carried out, I get an error:
"Could not open database file: /data/user/0/com.companyname.ACPlus_MobileEPOS/files/EPOSDatabase.db3 (CannotOpen)"
As a further debug test, I added this code to the startup of the application:
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
foreach (var file in Directory.GetFiles(path))
{
string strFile = Convert.ToString(file);
}
public readonly string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "EPOSDatabase.db3");
var db = new SQLiteConnection(dbPath);
db.CreateTable<Category>();
db.CreateTable<SystemSettings>();
db.Close();
In the foreach loop, it only found the original .zip file that I was trying to restore from.
Then when it reaches the line
var db = new SQLiteConnection(dbPath);
it fails to create the database with the message
"Could not open database file: /data/user/0/com.companyname.ACPlus_MobileEPOS/files/EPOSDatabase.db3"
It seems like the file doesn't exist, so hasn't extracted properly, but if that was the case then why does it not just create a new database, rather than try to open it?
The extraction logic needs to be rechecked.
Specifically ExtractToDirectory.
Extracts all the files in the specified zip archive to a directory on the file system.
public static void ExtractToDirectory (string sourceArchiveFileName, string destinationDirectoryName);
In the original code
ZipFile.ExtractToDirectory(dbPath + "/" + fileToRestore, dbPath + "/EPOSDatabase.db3");
The contents of the zip file are extracting to a directory called {path}/EPOSDatabase.db3/.
If the goal was just to extract from the archive to the directory then only the directory location is required.
ZipFile.ExtractToDirectory(dbPath + "/" + fileToRestore, dbPath);
Additionally, a check should be done to make sure the desired file actually exists after the restore before deleting the old file.
//... extraction code omitted for brevity
if (!File.Exists(dbPath + "/EPOSDatabase.db3")) {
//...either throw error or alert that database is not present
//...could consider return old file back to original sate (optional)
} else {
File.Delete(dbPath + "/tempEPOS.db3");
}
Related
Hi I have a code that you can save file and give specific file naming.
the problem is how can I check if file exist in the folder directory.
What I'm trying to do is like this.
FileInfo fileInfo = new FileInfo(oldPath);
if (fileInfo.Exists)
{
if (!Directory.Exists(newPath))
{
Directory.CreateDirectory(newPath);
}
fileInfo.MoveTo(string.Format("{0}{1}{2}", newPath, extBox1t.Text + "_" + textBox2.Text + "_" + textBox3.Text, fileInfo.Extension));
im trying to add MessageBox.Show in the below
if (!Directory.Exists(newPath))
{
MessageBox.Show("File Exist. Please Rename!");
Directory.CreateDirectory(newPath);
But it does not work. Or is there a way to add extension name at the last part of filename it should like this
Example: STACKOVERFLOWDOTCOME_IDNUM_11162022_0
if STACKOVERFLOWDOTCOME_IDNUM_11162022 exist it will rename to STACKOVERFLOWDOTCOME_IDNUM_11162022_0
it will add _0 at the last part.
One way to do it is to write a method that extracts the directory path, name, and extension of the file from a string that represents the full file path. Then we can create another variable to act as the "counter", which we'll use to add the number at the end of the file name (before the extension). We can then create a loop that checks if the file exists, and if it doesn't we'll increment the counter, insert it into the name, and try again.
For example:
public static string GetUniqueFileName(string fileFullName)
{
var path = Path.GetDirectoryName(fileFullName);
var name = Path.GetFileNameWithoutExtension(fileFullName);
var ext = Path.GetExtension(fileFullName);
var counter = 0;
// Keep appending a new number to the end of the file name until it's unique
while(File.Exists(fileFullName))
{
// Since the file name exists, insert an underscore and number
// just before the file extension for the next iteration
fileFullName = Path.Combine(path, $"{name}_{counter++}{ext}");
}
return fileFullName;
}
To test it out, I created a file at c:\temp\temp.txt. After running the program with this file path, it came up with a new file name: c:\temp\temp_0.txt
Here's my code in moving excel file to be specific..
if (Directory.GetFiles(destinationPath, "*.xls").Length != 0)
{
//Move files to history folder
string[] files = Directory.GetFiles(destinationPath); //value -- D://FS//
foreach (string s in files)
{
var fName = Path.GetFileName(s); //12232015.xls
var sourcePath = Path.Combine(destinationPath, fName);
var destFile = Path.Combine(historyPath, fName); // -- D://FS//History
File.Move(fName, destFile);
}
}
But it gets an error of
Could not find file 'D:\Project\ProjectService\bin\Debug\12232015.xls'.
Why it finds under my project not on the specific folder i set?
Thank you.
You're only using the name of the file:
var fName = Path.GetFileName(s); //12232015.xls
//...
File.Move(fName, destFile);
Without a complete path, the system will look in the current working directory. Which is the directory where the application is executing.
You should use the entire path for the source file:
File.Move(sourcePath, destFile);
Explicitly specifying the full path is almost always the best approach. Relative paths are notoriously difficult to manage.
There is an Logical error. Change
File.Move(fName, destFile);
to
File.Move(sourcePath, destFile);
as fName only contains file name and not fullpath. The file is checked in working directory.
I'm currently developing a website using asp and c#. One of the pages allows registered users to upload files. These files get stored according to the user who is logged in. A directory is created when they hit upload with there login name and id.
string userDirectory = "\\Test\\Files\\ " + User.Identity.Name + " " + User.Identity.GetUserId();
if (!Directory.Exists(userDirectory))
{
Directory.CreateDirectory(userDirectory);
}
The directory gets created without an issue and file also gets uploaded. However the problem I am now facing is I'm trying to add a date stamp to a file if it already exist in the directory so I don't overwrite it. See the code below
string fileName = Path.Combine(userDirectory, FileUpload1.FileName);
if (!File.Exists(fileName))
{
FileUpload1.SaveAs(fileName);
}
else
{
fileName = string.Concat(
Path.GetFileNameWithoutExtension(fileName),
DateTime.Now.ToString("_yyyy_MM_dd_HH:mm:ss"),
Path.GetExtension(fileName)
);
FileUpload1.SaveAs(fileName);
}
This keeps giving me an error:
System.Web.HttpException: The SaveAs method is configured to require a rooted path, and the path 'Test.docx' is not rooted
Does anyone know where I'm going wrong? Thanks in advance
You have to append the directory name to the path, since you stripped it off (by using GetFileNameWithoutExtension):
string newFileName =
Path.Combine( Path.GetDirectoryName(fileName)
, string.Concat( Path.GetFileNameWithoutExtension(fileName)
, DateTime.Now.ToString("_yyyy_MM_dd_HH_mm_ss")
, Path.GetExtension(fileName)
)
);
Also note that using : in a file name is not supported, so I replace it with _.
I have a return a c# code to save a file in the server folder and to retrieve the saved file from the location. But this code is working fine in local machine. But after hosting the application in IIS, I can save the file in the desired location. But I can't retrieve the file from that location using
Process.Start
What would be the problem? I have searched in google and i came to know it may be due to access rights. But I don't know what would be exact problem and how to solve this? Any one please help me about how to solve this problem?
To Save the file:
string hfBrowsePath = fuplGridDocs.PostedFile.FileName;
if (hfBrowsePath != string.Empty)
{
string destfile = string.Empty;
string FilePath = ConfigurationManager.AppSettings.Get("SharedPath") + ConfigurationManager.AppSettings.Get("PODocPath") + PONumber + "\\\\";
if (!Directory.Exists(FilePath.Substring(0, FilePath.LastIndexOf("\\") - 1)))
Directory.CreateDirectory(FilePath.Substring(0, FilePath.LastIndexOf("\\") - 1));
FileInfo FP = new FileInfo(hfBrowsePath);
if (hfFileNameAutoGen.Value != string.Empty)
{
string[] folderfiles = Directory.GetFiles(FilePath);
foreach (string fi in folderfiles)
File.Delete(fi);
//File.Delete(FilePath + hfFileNameAutoGen.Value);
}
hfFileNameAutoGen.Value = PONumber + FP.Extension;
destfile = FilePath + hfFileNameAutoGen.Value;
//File.Copy(hfBrowsePath, destfile, true);
fuplGridDocs.PostedFile.SaveAs(destfile);
}
To retrieve the file:
String filename = lnkFileName.Text;
string FilePath = ConfigurationManager.AppSettings.Get("SharedPath") + ConfigurationManager.AppSettings.Get("PODocPath") + PONumber + "\\";
FileInfo fileToDownload = new FileInfo(FilePath + "\\" + filename);
if (fileToDownload.Exists)
Process.Start(fileToDownload.FullName);
It looks like folder security issue. The folder in which you are storing the files, Users group must have Modify access. Basically there is user(not sure but it is IIS_WPG) under which IIS Process run, that user belongs to Users group, this user must have Modify access on the folder where you are doing read writes.
Suggestions
Use Path.Combine to create folder or file path.
You can use String.Format to create strings.
Create local variables if you have same expression repeating itself like FilePath.Substring(0, FilePath.LastIndexOf("\\") - 1)
Hope this works for you.
You may have to give permissions to the application pool that you are running. see this link http://learn.iis.net/page.aspx/624/application-pool-identities/
You can also use one of the built-in account's "LocalSystem" as application pool identity but it has some security issue's.
Hello everyone and well met! I have tried a lot of different methods/programs to try and solve my problem. I'm a novice programmer and have taken a Visual Basic Class and Visual C# class.
I'm working with this in C#
I started off by making a very basic move file program and it worked fine for one file but as I mentioned I will be needing to move a ton of files based on name
What I am trying to do is move .pst (for example dave.pst) files from my exchange server based on username onto a backup server in the users folder (folder = dave) that has the same name as the .pst file
The ideal program would be:
Get files from the folder with the .pst extension
Move files to appropriate folder that has the same name in front of the .pst file extension
Update:
// String pstFileFolder = #"C:\test\";
// var searchPattern = "*.pst";
// var extension = ".pst";
//var serverFolder = #"C:\test3\";
// String filename = System.IO.Path.GetFileNameWithoutExtension(pstFileFolder);
// Searches the directory for *.pst
DirectoryInfo sourceDirectory = new DirectoryInfo(#"C:\test\");
String strTargetDirectory = (#"C:\test3\");
Console.WriteLine(sourceDirectory);
Console.ReadKey(true);>foreach (FileInfo file in sourceDirectory.GetFiles()) {
Console.WriteLine(file);
Console.ReadKey(true);
// Try to create the directory.
System.IO.Directory.CreateDirectory(strTargetDirectory);
file.MoveTo(strTargetDirectory + "\\" + file.Name);
}
This is just a simple copy procedure. I'm completely aware. The
Console.WriteLine(file);
Console.ReadKey(true);
Are for verification purpose right now to make sure I'm getting the proper files and I am. Now I just need to find the folder based on the name of the .pst file(the folder for the users are already created), make a folder(say 0304 for the year), then copy that .pst based on the name.
Thanks a ton for your help guys. #yuck, thanks for the code.
Have a look at the File and Directory classes in the System.IO namespace. You could use the Directory.GetFiles() method to get the names of the files you need to transfer.
Here's a console application to get you started. Note that there isn't any error checking and it makes some assumptions about how the files are named (e.g. that they end with .pst and don't contain that elsewhere in the name):
private static void Main() {
var pstFileFolder = #"C:\TEMP\PST_Files\";
var searchPattern = "*.pst";
var extension = ".pst";
var serverFolder = #"\\SERVER\PST_Backup\";
// Searches the directory for *.pst
foreach (var file in Directory.GetFiles(pstFileFolder, searchPattern)) {
// Exposes file information like Name
var theFileInfo = new FileInfo(file);
// Gets the user name based on file name
// e.g. DaveSmith.pst would become DaveSmith
var userName = theFileInfo.Name.Replace(extension, "");
// Sets up the destination location
// e.g. \\SERVER\PST_Backup\DaveSmith\DaveSmith.pst
var destination = serverFolder + userName + #"\" + theFileInfo.Name;
File.Move(file, destination);
}
}
System.IO is your friend in this case ;)
First, Determine file name by:
String filename = System.IO.Path.GetFileNameWithoutExtension(SOME_PATH)
To make path to new folder, use Path.Combine:
String targetDir = Path.Combine(SOME_ROOT_DIR,filename);
Next, create folder with name based on given fileName
System.IO.Directory.CreateDirectory(targetDir);
Ah! You need to have name of file, but with extension this time. Path.GetFileName:
String fileNameWithExtension = System.IO.Path.GetFileName(SOME_PATH);
And you can move file (by File.Move) to it:
System.IO.File.Move(SOME_PATH,Path.Combine(targetDir,fileNameWithExtension)
Laster already show you how to get file list in folder.
I personally prefer DirectoryInfo because it is more object-oriented.
DirectoryInfo sourceDirectory = new DirectoryInfo("C:\MySourceDirectoryPath");
String strTargetDirectory = "C:\MyTargetDirectoryPath";
foreach (FileInfo file in sourceDirectory.GetFiles())
{
file.MoveTo(strTargetDirectory + "\\" + file.Name);
}