|
Subject:
|
GetFiles() Help
|
|
Posted By:
|
adamcherochak
|
Post Date:
|
4/4/2008 3:43:32 PM
|
Greetings, I need help with a GetFiles() to return multiple file extensions. I think I am close with the included bit of code. However, it is not filtering like I desire. It returns all files if any file has an extension of my If statement. I want it to return only those files with the desired extension.
I think I might need a table adapter but I'm not using a database.
Dim dirInfo2 As NewDirectoryInfo(Server.MapPath("///.\UploadFolder\"))
Dim fileArray As FileInfo() = dirInfo2.GetFiles()
Dim specificFile As FileInfo
For Each specificFile In fileArray
If specificFile.Extension = ".htm" Then
'add to data source
dgArticleList.DataSource = fileArray 'PROBLEM HERE
End If
Next specificFile
dgArticleList.DataBind()
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/5/2008 1:51:17 AM
|
Hi Adam,
There are a couple of ways to do this. First of all, you can use the static GetFiles method of the Directory class and pass it a search pattern. This only gives you the name of the file as a string though:Dim basePath As String = Server.MapPath("~/")
Dim searchPattern As String = "*.aspx"
dgArticleList.DataSource = Directory.GetFiles(basePath, searchPattern)
dgArticleList.DataBind()Alternatively, you can do the same with your code and pass the wild card pattern to GetFiles of your DirectoryInfo instance:' Assumes you have basePath and searchPattern from example 1
Dim dirInfo As New DirectoryInfo(basePath)
dgArticleList.DataSource = dirInfo.GetFiles(searchPattern)
dgArticleList.DataBind() Finally, and much cooler you can use LINQ (if you are using .NET 3.5). With LINQ you can express queries in a much more natural way and get files based on much more criteria than their extension alone. Just for fun, the following code gets all ASPX files that have been created in the past 24 hours and that have been accessed in the last 10 minutes:Dim list = From f In New DirectoryInfo(basePath).GetFiles _
Where f.CreationTime > DateTime.Now.AddHours(-24) _
And f.LastAccessTime > DateTime.Now.AddMinutes(-10) _
And f.Extension.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase) _
Select f
dgArticleList.DataSource = list
dgArticleList.DataBind()Hope this helps,
Imar
--------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|
|
Reply By:
|
adamcherochak
|
Reply Date:
|
4/5/2008 1:06:06 PM
|
Imar,
As usual, your code is awesome! I am truly impressed with the LINQ example! However, I'm trying to pass multiple patterns to GetFiles().
searchPattern returns all file types which is stored in an array of FileInfo(). I then use two separate arrays to loop through everything then store the files with the desired extensions which becomes my DataSource.
I've modified my code to match your example, but I am at a complete loss inside the nested IF Statement. I cannot use .Add in there.
Dim basePath As String = Server.MapPath("~/UploadFolder/")
Dim searchPattern As String = "*.*"
Dim dirInfo As New DirectoryInfo(basePath)
Dim fileArray As FileInfo() = dirInfo.GetFiles(searchPattern)
Dim specificFile As FileInfo
Dim secondArray As FileInfo
For Each specificFile In fileArray
If specificFile.Extension = ".htm" Or specificFile.Extension = ".ppt" Then
'collect files with desired extensions
secondArray.Add(specificFile)
End If
Next specificFile
dgArticleList.DataSource = secondArray
dgArticleList.DataBind()
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/5/2008 1:58:40 PM
|
You're not declaring secondArray as an array (using ()) but even if you would, it wouldn't have an Add method. Instead of an array you can use a generics List (Of FileInfo) instance like this:Imports System.Collections.Generic
Dim specificFile As FileInfo
Dim filteredList As New List(Of FileInfo)
For Each specificFile In fileArray
If specificFile.Extension = ".htm" Or specificFile.Extension = ".ppt" Then
'collect files with desired extensions
filteredList.Add(specificFile)
End If
Next specificFile
dgArticleList.DataSource = filteredList
dgArticleList.DataBind() If you don't want GetFiles to do any filtering, there's no need to pass *.* as the search pattern. The parameterless version of GetFiles gets all files by default.
Cheers,
Imar
--------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|
|
Reply By:
|
adamcherochak
|
Reply Date:
|
4/5/2008 2:28:29 PM
|
Imar,
You are a genius!! Your List(Of FileInfo) solution was exactly what I needed! It correctly filled my datagrid with the multiple-filters.
Thank you so much for your help!
Problem Solved.
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/5/2008 2:45:53 PM
|
You're welcome.....
Imar --------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|
|
Reply By:
|
adamcherochak
|
Reply Date:
|
4/16/2008 10:43:45 PM
|
Hello Again,
I am using the code posted above, it works perfectly (thank you Imar!). I am now attempting to change the file name just before it is collected in the "filteredList" array. I'm thinking I might need to convert from stream to string for this to work??...
The included code shows my feeble attempt change the file name. I would prefer to prefix the file name based on the first character of the file name.
Ideally my DataGrid row would display a custom custom file name like this: Original File Name= 1myFile.txt Modified File Name= CSTLRKmyFile.txt
For Each specificFile In fileArray
If specificFile.Extension = ".txt" Or specificFile.Extension = ".doc" Then
If specificFile.Name.StartsWith("1") Then
specificFile.Replace(specificFile.FullName, "CSTLRK")
'collect files with desired extensions and new name
filteredList.Add(specificFile)
End If
End If
Next specificFile
dgArticleList.DataSource = filteredList
dgArticleList.DataBind()
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/17/2008 8:48:23 AM
|
Hi there,
First of all, you're not really replacing the value. Or actually, it looks like you are replacing, but you don't assign the value back:
specificFile.Replace(specificFile.FullName, "CSTLRK")
The return value of the Replace operation is completely ignored.
Also, Replace doesn't replace the file name, it replaces the *underlying* file on disk: http://msdn2.microsoft.com/en-us/library/system.io.fileinfo.replace.aspx
Finally, most of the properties of the FileInfo are read-only so you can't really reassign a new file name.
Instead, create an intermediate object, fill that with the name of the file and add that object to your list that you bind to your grid.
What that intermediate object is depends; ot could be as simple as a string of all you need is the file name. You could also create a simple custom class for this purpose.
Cheers,
Imar
--------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/17/2008 8:54:28 AM
|
BTW: as an alternative, you can change the file name in one of the data events of your DataGrid, like ItemDataBound. That way, you can still bind your FileInfo list, but only change the name when it;s displayed.
Finally, you could create a little helper method that does this. Something like this in your Grid:
... <%# ConvertFileName(Eval("FullName")) %> ...
With this code in the Code Behind:
Protected Function ConvertFileName(ByVal fileName As Object) As String Dim localFileName As String = CType(fileName, String) If localFileName.EndsWith(.....) Return "WhatEverYouWant" End If Return localFileName End Function
Hope this helps,
Imar --------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|
|
Reply By:
|
adamcherochak
|
Reply Date:
|
4/17/2008 1:07:56 PM
|
Imar,
Just as I was about to give up and beg you for more help, I re-read your instructions and got it to work successfully!!
Problem solved.
Again, I am grateful and inspired by your expert code examples, and clear advice.
I am curious about your suggestion to create a custom class, do you have an example I could follow?
Here is the final code, I was using the HyperLinkColumn unsuccessfully at first. Then, I tried a TemplateColumn with your helper method and code-behind:
ASPX PAGE
<Columns>
<asp:TemplateColumn HeaderText="File Name">
<ItemTemplate>
<asp:HyperLink ID="hyprLnk1" runat="server" Target="_self"
Text='<%# ConvertFileName(Eval("Name")) %>'
NavigateUrl="javascript:LoadIFrame('../../UploadFolder/{0}');">
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
VB CODE-BEHIND
Protected Function ConvertFileName(ByVal fileName As Object) As String
Dim localFileName As String = CType(fileName, String)
If localFileName.StartsWith("1") Then
Return "CSTLRK"
End If
Return localFileName
End Function
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/17/2008 4:43:43 PM
|
I had something like this in mind (untested, typed directly in this forum thread and only just used to show the general idea):
[FileSummary.vb]
Public Class FileSummary
Public Sub New(ByVal fileName As String)
_fileName = fileName
End Sub
Private _fileName As String
Public Property FileName() As String
Get
Return _fileName
End Get
Set(ByVal Value As String)
_fileName = Value
End Set
End Property
End Class Then in our ASPX file:Dim fileSummaries As New List(Of FileSummary)
For Each specificFile In fileArray
If specificFile.Extension = ".txt" Or specificFile.Extension = ".doc" Then
If specificFile.Name.StartsWith("1") Then
fileSummaries.Add(New FileSummary("CSTLRK"))
Else
fileSummaries.Add(New FileSummary(specificFile.Name))
End If
End If
Next specificFile
dgArticleList.DataSource = fileSummaries
dgArticleList.DataBind()This way, you create a generics list of FileSummary instances that do nothing more than contain the filename. The constructor that accepts the file name is used to make it easier to construct new instances of FileSummary.
Hope this helps,
Imar --------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|
|
Reply By:
|
adamcherochak
|
Reply Date:
|
4/18/2008 8:37:44 PM
|
Imar,
This is BRILLIANT!! Thank you so much for your guidance!
|
|
Reply By:
|
Imar
|
Reply Date:
|
4/19/2008 7:21:57 AM
|
Hi Adam,
You're welcome. Have fun with it....
Imar --------------------------------------- Imar Spaanjaars http://Imar.Spaanjaars.Com Everyone is unique, except for me. Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004 Want to be my colleague? Then check out this post.
|