copy media files from one folder to another, but rename the files - asp.net

I want to have a function in my game manager that "clones" a game. So far I have all the cloning working except cloning the game media.
I want the media to clone/copy like this:
basePath + gameId + mediaFile
So a simple example would look like this:
--- original game
c:\inetpub\wwwroot\spac_rpg\MediaFiles\12\33d43636-275b-4b92-8778-cf591829103e.png
c:\inetpub\wwwroot\spac_rpg\MediaFiles\12\57ea0ad8-c69a-45e7-951e-d0325aa404ab.mov
becomes
--- new clone of the game (notice the different gameIds and the different GUID Ids for the media)
c:\inetpub\wwwroot\spac_rpg\MediaFiles\13\4427a554-b6a7-457a-b5ff-7c7cb7aee5bb.png
c:\inetpub\wwwroot\spac_rpg\MediaFiles\13\e9371c5d-eb47-4014-8380-204f7aff44fb.mov
So far I have this, which isn't much, but I'm kinda stuck on where to go next:
' copy each media file to new folder with new name
' new and old media file IDs
Dim newMediaId As Guid
Dim oldMediaId As Guid
Dim oldGameId As Int
' base path for game media
Dim basePath = "C:\inetpub\wwwroot\spac_rpg\MediaFiles\"
' new media folder
Dim newMediaFolder = Directory.CreateDirectory(basePath & newGameId)
' XXX ds is a dataset that is returned from the database with the old and new mediaIDs
For Each dr As DataRow In ds.Tables(0).Rows
oldMediaId = dr("oldMediaID")
newMediaId = dr("newMediaID")
Dim oldFile = (basePath & oldGameId & "\" & oldMediaId)
Dim clonedFile = (basePath & newGameId & "\" & newMediaId)
Next
Or maybe I'm trying to break this down to much and there's a much easier way of copying?
I just need to make sure that the new folder with the new GameId is created and that each new media file is cloned with the newMediaId that is returned from the database call.
Thanks!

The System.IO.File.​Copy can do the copy for you. It takes the source file and destination file (which can be different) as parameters).
System.IO.File.​Copy(oldFile, clonedFile)

Related

Get only part of file name and delete from server folder in asp.net vb

I'm trying get get only the last part of a file name in a server folder between the "_" and ".pdf" in order to delete specific files only.
The files in the invoices folder are like this: Invoice_12345.pdf, Invoice_2345.pdf, Invoice_5555.pdf, etc. I need to extract the "12345", "2345", and "5555", then I need to delete the file if it is not contained in a database query.
With the following code, I wish to extract the digits from the files in the folder, so how do I get the number between "_" and ".pdf"?
Dim files() As String = Directory.GetFiles(Server.MapPath("/Contents/Invoices/"))
For Each file As String In files
list.Add(file)
Next
Then I need to delete the file from the server if the extracted number is not contained in a dataset I query from the database, but maybe that is a question for a different post.
For example, for Invoice "5555"
If PaidFull = True
File.Delete(file)
End If
Of course, I would have to then get the full file name to delete if from the server at that point.
This is a way to get only the numbers :
For Each file As String In files
Dim the_number As String = Path.GetFileNameWithoutExtension(file)
the_number = the_number.Substring(the_number.LastIndexOf("_") + 1, the_number.Length - the_number.LastIndexOf("_") - 1)
list.Add(the_number )
Next
Or with Regex (ty to Jimi) :
dim the_number = Regex.Match(file, "_(\d+)\.").Groups(1).Value
You really don't need to mess with parsing the file name if you are sure the number won't pop up somewhere in the directory path.
'Dim list = Directory.GetFiles("C:\SomeDirectory").ToList
Dim myTestList As New List(Of String) From {"Invoice_12345.pdf", "Invoice_2345.pdf", "Invoice_5555.pdf"}
For Each fileName In myTestList
If fileName.Contains("5555") Then
Debug.Print(fileName) 'Or do what you need to do
End If
Next

Rename file name based on upload date

I write the below code to copy the file and rename file name but the problem that i have now that i need to pick the last file (based on upload date) then rename the file , the below code change all files placed in the folder regardless the upload date , also if there is a simple code to upload file check if file is exist then show message (successful upload , failed upload (duplicate file))
Dim directory = Server.MapPath("App_Data/text/")
For Each filename As String In IO.Directory.GetFiles(directory, "*", IO.SearchOption.AllDirectories)
Dim fName As String = IO.Path.GetFileName(filename)
If fName.ToString Like "*Cust*" Then
System.IO.File.Delete(Server.MapPath("App_Data\test\Customer.txt"))
My.Computer.FileSystem.CopyFile(Server.MapPath("App_Data\text\" & fName), Server.MapPath("App_Data\test\" & fName))
My.Computer.FileSystem.RenameFile(Server.MapPath("App_Data\test\" & fName), "Customer.txt")
you can use below code and find creation date and last modified date of a file:
Dim creation as DateTime = File.GetCreationTime(#"C:\test.txt")
Dim modification as DateTime = File.GetLastWriteTime(#"C:\test.txt")
or by Importing System.IO and using this code:
Dim fi as FileInfo = new FileInfo("path")
Dim created = fi.CreationTime
Dim lastmodified = fi.LastWriteTime
i think the second one is better because you can put them in a collection easily and then sort them or compare them.

HttpPostedFile and SaveAs not saving a part of the path

I'm trying to save a file that is uploaded using an HttpPostedFile control.
The main issue I'm running into, is that it won't create a new folder for the file.
In the code below, "file" is an HttpPostedFile.
So I have my base path that I define like this:
Dim basePath = "D:\\game\\world\\map\\MediaFiles\\"
Then I get the file name like this:
Dim fileName = Path.GetFileName(file.FileName)
Now I want to create a new path like this using the gameId (guid):
Dim newFolderAndFile As String = gameId + fileName
And then combine the path with the base path and save:
Dim saveAsPath = Path.Combine(basePath, newFolderAndFile)
file.SaveAs(saveAsPath)
But when I try that, I always get an error like this:
System.IO.DirectoryNotFoundException: Could not find a part of the
path
'D:\game\world\map\MediaFiles\05a10e9c-e8a9-49ed-ad4f-34b6b4650ef3\5.jpg'
So it looks like the saveAsPath is being constructed correctly, however SaveAs isn't saving it.
How can I get SaveAs to create the path and file?
Thanks!
As the_lotus explained, you need to create the directory first before saving the file
Dim basePath = "D:\game\world\map\MediaFiles\"
Dim fileName = Path.GetFileName(file.FileName)
' make new folder
system.io.direcotry.createdirectory(basepath & gameid)
Dim saveAsPath = (basePath & gameid & "\" & filename)
file.SaveAs(saveAsPath)
I'm not sure about the double slashes, I think that's not needed...

Append created PDF page with existing PDF file with iTextSharp

I'm currently in the process of creating (what I thought would have been) a really simple method to append two PDF files.
Firstly, my method creates a page that has all of the clients details on it as a digital signature. I had this working fine and saving to a single page PDF file.
However, I now want to append the terms & conditions that they're signing to the bottom of the PDF. The solution I'm coding in uses VB.NET, but you can provide the answer in C# if you prefer because I'm familiar with both. I just seriously cannot get my head around iTextSharps process.
Here is my code currently:
Public Sub CreateDocument() Handles btnCreate.ServerClick
Dim path As [String] = Server.MapPath("PDFs")
Dim document As New Document()
Dim writer As PdfWriter = PdfWriter.GetInstance(document, New FileStream(path + "/" + _AccountNo + "-RegAgreement.pdf", FileMode.Create))
'Removed chunk of code here, just defining content chunks and paragraphs
for the dynamically created page, left in the construction
part which you can see below'
'Construct digitally signed agreement page'
document.Open()
document.NewPage()
document.Add(pHeader)
table.SpacingBefore = 30.0F
table.SpacingAfter = 60.0F
document.Add(table)
pAgreement.SpacingAfter = 20.0F
document.Add(pAgreement)
document.Add(pSignedBy)
document.Add(imgSig)
document.Add(pFooter1)
document.Add(pFooter2)
document.Add(pFooter3)
writer.Close()
document.Close()
Now this is the bit I've added to the end of the above sub to append the PDF. As far as I'm aware, you need to use the PdfCopy to transfer the information from the PDF to a new Document object (In this case, doc). But then, I can't find a way to add these to the dynamically created PDF.
Is there perhaps a way to open it within the copier and then start copying from page 2?
Dim terms As New PdfReader(path + "/termsconditions.pdf")
Dim doc As New Document()
Dim copier As New PdfCopy(doc, New FileStream(path + "/" + _accountNo + "-RegAgreement2.pdf", FileMode.Create))
'Append Ts & Cs'
For i As Integer = 1 To terms.NumberOfPages
Dim importedPage As PdfImportedPage = copier.GetImportedPage(terms, i)
copier.AddPage(importedPage)
Next
terms.Close()
terms.Close()
End Sub
Every solution I've seen so far has used different methods like page stamps or memory streams, but none of them have worked or given me the result I need.
Any help is greatly appreciated!
UPDATE
Okay so after #mkl's suggestion, I have now brought the dynamically generated document back with a reader, however it's returning a null value suggesting that the .PDF is blank, but it isn't. (I have the file in my directory with all the content filled)
Dim copier As New PdfCopy(document, New FileStream(path + "/" + _distNo + "-RegAgreement2.pdf", FileMode.OpenOrCreate))
Dim reader As New PdfReader(path + "/" + _distNo + "-RegAgreement.pdf")
'retrieve dynamic document
Dim dynamicPage As PdfImportedPage = copier.GetImportedPage(reader, 1)
copier.AddPage(dynamicPage)
'Append Ts & Cs
For i As Integer = 1 To terms.NumberOfPages
Dim importedPage As PdfImportedPage = copier.GetImportedPage(terms, i)
copier.AddPage(importedPage)
Next
Is this because it's being done within the same subroutine?
Solved, big thanks to #mkl on this one.
The issues I was facing were because I wasn't creating a Document object for the copier to write to.
Dim doc As New Document()
Dim copier As New PdfCopy(doc, New FileStream(path + "/" + _distNo + "-RegAgreement.pdf", FileMode.Create))
'Open PDF created earlier in subroutine'
Dim reader As New PdfReader(path + "/" + _distNo + "-Signed.pdf")
doc.Open()
'Copy first (And only) page of dynamic PDF'
Dim dynamicPage As PdfImportedPage = copier.GetImportedPage(reader, 1)
copier.AddPage(dynamicPage)
'Append Ts & Cs'
For i As Integer = 1 To terms.NumberOfPages
Dim importedPage As PdfImportedPage = copier.GetImportedPage(terms, i)
copier.AddPage(importedPage)
Next
doc.Close()
terms.Close()
reader.Close()
copier.Close()
'For temporary purposes, delete local file'
'This will be done in output stream in end release'
File.Delete(path + "/" + _distNo + "-Signed.pdf")
Thanks for the help guys. Think I've got the basic procedures of this iTextSharp thing down now!

is there a way to query a stream in c#, ex. select * from a streamobject

I have a file upload control in my asp.net (c#) website, which is used to upload csv files with data to be inserted into the database, my problem is that, I was not able to get the actual path of the uploaded file
It always gave me: C:\inetput\projectfolder\csvname.csv
where it should have been similar to: C:\Documents and settings\Pcname\Desktop\csvname.csv
but by going through the various post of file upload, i came to know that file need to be saved on the server first,
using Fileupload1.Saveas(savepath);
which is mandatory to save the file in a previously specified location, where this not actually required. (since it will increase the overhead of again deleting the file).
then what I do is as below:
bool result = true;
strm = FileUpload1.PostedFile.InputStream;
reader2 = new System.IO.StreamReader(strm);
// **** new ****
FileInfo fileinfo = new FileInfo(FileUpload1.PostedFile.FileName);
string savePath = "c:\\"; // example "c:\\temp\\uploads\\"; could be any path
string fileName = fileinfo.Name;
string strFilePath = savePath.ToString();
savePath += fileName;
FileUpload1.SaveAs(savePath);
string strSql = "SELECT * FROM [" + fileinfo.Name + "]";
string strCSVConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strFilePath + ";" + "Extended Properties='text;HDR=NO;'";
// load the data from CSV to DataTable
OleDbDataAdapter oleda = new OleDbDataAdapter(strSql, strCSVConnString);
DataTable dtbCSV = new DataTable();
oleda.Fill(dtbCSV);
if (dtbCSV.Columns.Count != 2)
{
result = false;
}
because I want to count the number of columns in the file, I'm using the oledb reader.
which needs a file to be queried.
Is it possible to Query a stream? I dont want to save the file, instead just read it without saving.
Unfortunately you cannot use OLEDB against a stream.
In situations where it is mandatory to use OLEDB I've managed to write an IDisposable wrapper that would provide a temporary file from a stream and manage deletion.
You could however go for an alternate approach to reading the contents, without saving it, such as parsing the file yourself directly from a stream. I would recommend this instead of the wrapper since you avoid file access restriction problems as well as the overhead of file access.
Here's an SO with several different approaches.

Resources