הקדמה
| הערה:
מערכת הקבצים שאיתה נעבוד שייכת לשרת ולכן יש לשים לב שיש לכם הרשאות מתאימות בשרת. (הערה זו אינה תקפה אם הינכם מתכוונים להריץ קוד זה ב-PWS ולא בשרת)
|
| מודל האובייקט |
| אובייקט הכונן (Drive Object) |
נותן גישה לדיסק או לכונן רשת |
| אובייקט מערכת הקבצים (FileSystemObject Object) |
נותן גישה למערכת קבצים של מחשב מסוים |
| אובייקט הספרייה (Folder Object) |
נותן גישה לכל מאפייני ספריות |
| אובייקט זרימת הטקסט (TextStream Object) |
נותן גישה נוחה לתוכן קובץ מסויים |
שימוש לא נכון באובייקט חזק זה יכול לגרום לבעיות רציניות, השתמשו בו בתבונה!
| הערה:
אובייקט מערכת הקבצים מסופק ע"י מיקרוסופט ולכן הפעלתו במערכות הפעלה אחרות אינו מומלץ (בלשון המעטה)
|
שימוש באובייקט:
כדי להשתמש באובייקט עלינו קודם כל להורות לשרת ליצור אותו,
אם עבדתם בעבר עם אובייקטים ב-ASP שורות הקוד הבאות לא יהוו הפתעה גדולה.
Set FSO = Server.CreateObject("Scripting.FileSystemObject")
כאן יצרנו והגדרנו את האובייקט.
עכשיו נוכל להשתמש בצורה המוכרת של אובייקט.שיטה
ללמוד עוד על תכנות מונחה עצמים ב-VB לחצו כאן
הערה:
מודל ה-FSO הוא חלק מהרכיב scrrun.dll ,
ניתן להשתמש באובייקט לא רק באפליקציות ASP אלא בכל אפליקציה תומכת אובייקטים (ACCESS, WORD, EXCELL...)
והוא אינו מוגבל רק לאפליקציות ASP.
|
להל"ן רשימה חלקית של שיטות ב-FSO שנישתמש בהן כאן לביצוע הסבה ופעולות שונות עם קבצים:
| שיטות |
| CopyFile |
מעתיק קובץ אחד או יותר ממקום אחד לאחר |
| CreateTextFile |
יוצר קובץ ומחזיר אובייקט TextStream |
| DeleteFile |
מוחק קובץ |
| OpenTextFile |
פותח קובץ ומחזיר אובייקט TextStream שיכול לשמש לקריאה או להוספה לקובץ |
לרשימה מלאה של כל השיטות והמאפיינים לחץ כאן
בואו נעבור לכמה דוגמאות:
כתיבת קבצים
נניח שאתה רוצה ליצור אפליקצייה של ספר אורחים בה גולשים יכולים להרשם בו ולכתוב מידע על עצמם. אתה יכול ליצור מסד נתונים ולשמור שם את המידע. אבל, אם אתה לא צריך את הכח של מסד הנתונים, אתה יכול לחסוך לעצמך כסף ומאשבים ופשוט להשתמש פה באובייקט ה-FSO ובעזרתו לשמור את המידע על הגולשים. שלא נזכיר את העובדה שהשרת בו אתרך מאוכסן יכול להגביל אותך באפשרויות משחק עם מסדי נתונים.
בואו ונניח שאספתם מידע מסויים על משתמש בעזרת טופס. להלן קוד של טופס פשוט לקבלת המידע:
בואו נביט בקוד אשר מטפל במידע שנשלח מהטופס אותו כתבנו למעלה:
<%
[קבלת מידע מהטופס]
strName = Request.Form("username")
strHomePage = Request.Form("homepage")
strEmail = Request.Form("Email")
[יצירת האובייקט]
Set fso = Server.CreateObject("Scripting.FileSystemObject")
%>
עד כאן, לא עשינו בעצם שום דבר חדש. קראנו את המידע שנשלח מהטופס והכנסנו אותו לתוך משתנים בשביל שימוש פשוט וקל יותר.
כעת, מגיע החלק הכייפי. כתיבת הקובץ:
path = "c: emp est.txt"
ForReading = 1, ForWriting = 2, ForAppending = 3
[פתיחת קובץ טקסט]
set file = fso.opentextfile(path, ForAppending, TRUE)
[כתיבת המידע לתוך הקובץ]
file.write(strName) & vbcrlf
file.write(strHomePage) & vbcrlf
file.write(strEmail) & vbcrlf
[סגור קובץ ונקה משתנים]
file.close
set file = nothing
set fso = nothing
כזכור, שיטת ה-OpenTextFile מחזירה אובייקט TextStream אשר הוא אובייקט נוסף של מודל ה-FSO.
אובייקט ה-TextStream מאפשר שיטות למשחק עם תוכן הקבצים, כגון: כתיבה, קריאה, דילוג על שורות ועוד.
קבוע ה vbCrlf יוצר שבירת שורה (ENTER)
| הערה:
קבענו ערך TRUE בקריאה ל-OpenTextFile אשר אומר למערכת ליצור את הקובץ במידה ואינו קיים כבר. אם הקובץ אינו קיים ולא נתנו את ערך TRUE, נקבל הודעת שגיאה מכוערת.
|
כעת, לך לספרייה c: emp ופתח את קובץ test.txt
אתה אמור לראות בו את הטקסט הבא:
Users name
Users home page
Users email
כמובן ששורות אלו יתחלפו עם המידע אותו הכניס הגולש בטופס. כעת כל גולש יכול לגשת לטופס והרשם בספר האורחים שלנו!
קריאת קבצים
כעת יש לנו מעט מידע נחמד שמור בתוך קובץ, אשר מתפקד כמו מסד נתונים פשוט. כעת נניח שמשתמש מגיע ורוצה לראות את כל המבקרים שלך. עלינו להציג את המידע בצורה כלשהי. מכיוון שאנו לא משתמשים במסד נתונים עם מבנה של עמודות, נאלץ להתחכם בכדי להוציא מהקובץ את התוצאות הרצויות.
אנו יודעים שבקובץ שיצרנו, השורה הראשונה הינה שם המשתמש, השניה הינה דף הבית שלו, והשלישית הינה כתובת הדואר האלקטרוני שלו. כל משתמש שיתווסף לקובץ, המידע שלו יתווסץ באותה צורה, כך שכל שורה שלישית למשל, תכיל את אותו סוג מידע (דואר אלקטרוני)
ולכן, בכדי לקרוא מידע מהקובץ, נכתוב את הקוד הבא:
<%
[יצירת אובייקט]
set fso = Server.Createobject("Scripting.FileSystemObject")
path = "c: emp est.txt"
[פתיחת קובץ טקסט]
set file = fso.opentextfile(path, 1) <-- לקריאה
%>
כעת, בואו ונכתוב כל שורה ושורה בצורה נכונה:
<%
do until file.AtEndOfStream
Response.write("Name: " & file.ReadLine & " ")
Response.write("Home Page: " & file.ReadLine & " ")
Response.write("Email: " & file.ReadLine & "")
loop
[סגירת אובייקט ואיפוס משתנים]
file.close
set file = nothing
set fso = nothing
%>
| הערה:
מה שעשינו היה הדפסה פשוטה של המידע שבקובץ, אז יש לזכור שניתן גם לכתוב את המידע בתוך טבלאות ואף להשתמש בעיצוב DHTML.
|
אם יצרת וכתבת את הקובץ כמו שצריך, הלולאה הפשוטה פשוט תציג רשימה של כל המשתמשים.
שיטת ה-ReadLine קוראת שורה אחת עד שמגיעה לתו ה-newline שמסמל שורה חדשה.
קריאה חוזרת לשיטת ה-ReadLine תקרא את השורה הבאה וכך הלאה.
AtEndOfStream הוא מאפיין של אובייקט זרימת הטקסט (TextStream) אשר מאפשר לנו לדעת שהגענו לסוף הקובץ.
נניח שמסיבה כלשהי לא עיצבנו נכון את הקובץ. אם למשתמש יש רק 2 שורות במקום 3 אשר מתארות את המידע, אזי נקבל כאן הודעות שגיאה. הלולאה שלנו מקבלת את 3 השורות הבאות בקובץ ואם אין 3 שורות, הדף ישתגע ויזרוק לנו הודאת שגיאה כגון:
Server object error ASP 0177 : 800a003e
ומכיוון שאתה לא אוהב הודעות שגיאה, כדאי לך לוודא שאתה לא מדלג או מכניס יותר מידי שורות לקובץ.
הרשאות
כעת, לאחר שכיסינו את הבסיס, נדון בהרשאות. ה-FSO רץ אצל המשתמש שיצר אותו. במילים אחרות, אם מישהו מגיע אל הדף שלך דרך האינטרנט, אזי משתמש האינטרנט ייצור את ה-FSO.
אם נכנסת למחשב שלך דרך סיסמאת הAdministrator ואתה נכנס לדף, אזי משתמש ה-Administrator ייצור את ה-FSO.
זהו דבר מאוד חשוב, מכיוון של משתמשים שונים יש הרשאות שונות, ובכדי שה-FSO יתפקד בצורה מלאה הוא צריך הרשאות מתאימות.
בדרך כלל, משתמש האינטרנט מקבל הרשות קריאה בלבד. זה אומר שהמשתמשים לעולם לא יוכלו לכתוב משהו מקובף ספר האורחים למשל.
למרות זאת, ישנן מספר דרכים לעקוף זאת.
הראשונה, והמסובכת מבניהן היא לדרוש מהגולש להתחבר לשרת לפני שהם כותבים לספר אורחים. אך הרעיון של ספר האורחים הוא לקבל מידע מגולשים אנונימים, ובכדי שהגולש יתחבר לשרת עלינו לדעת מי הוא. לכן נדלג על דרך זו ונמשיך הלאה.
הדרך השניה היא ליצור ספרייה או קובץ שנותן הרשאות לגולש אינטרנט. דרך זו היא פוטנציאל לחורים באבטחה, מכיון שכל אחד שיודע היכן נצאת הספרייה ויש לו ידע נרחב, יוכל לכתוב דברים בתוך השרת שלך.
ואת זה אני משער שאתם לא רוצים אצלכם... אז צריך לוודא שיוצרים את הספרייה במקום מאובטח ומוחבא ואפילו רצוי למקם אותה מחוץ לספרייה האתר. (מחוץ לספריית inetpub למשל)
חיפוש בעזרת FSO
אתה בטח חושב: "מגניב, אז עכשיו אני יודע איך לכתוב קבצים, יכלתי גם להבין איך עושים זאת בעצמי.", אז אתה רוצה עוד? בואו ונבנה חיפוש באתר בעזרת FSO!
המפתח לחיפוש זה יהיה רקורסיה.
נכתוב קוד אשר מחפש בקבצים בספרייה מסויימת ואז, נפעיל את אותו קוד שיעבור על כל התת-ספריות של אותה ספרייה ויחפש בתוכם וכך הלאה...
מכיוון שאיננו יודעים כמה תת-ספריות יהיו בספרייה הראשית בה נרצה לחפש, נצטרך לקרוא לקוד ברקורסיה עד אשר החיפוש יעבור בכל התת-ספריות.
אז בואו ונבנה דף חיפוש, נניח שכבר בנית טופס HTML בכדי שהמשתמש יוכל להכניס את המחרוזת אותה ברצונו לחפש.
Dim objFolder
Dim strSearchText
Dim objFSO
strSearchText = Request.Form("SearchText") <-- מחרוזת החיפוש
[יוצר את אובייקט ה-FSO ואת אובייקט ה-FOLDER]
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(Server.MapPath("/"))
Search objFolder
הקוד למעלה מאתחל את המשתנים ומכין אותנו לפעולה. הבשר של הקוד נמצא ממש פה מתחת:
Function Search(objFolder)
Dim objSubFolder
[לולאה שעוברת על כל הקבצים בספרייה הנוכחית]
For Each objFile in objFolder.Files
Set objTextStream = objFSO.OpenTextFile(objFile.Path,1) <-- For Reading
[קריאת כל תוכן הקובץ לתוך משתנה]
strFileContents = objTextStream.ReadAll
[אם מחרוזת החיפוש נמצאה בתוכן הקובץ, ניצור קישור אל הקובץ]
If InStr(1, strFileContents, strSearchText, 1) then
Response.Write "" & objFile.Name & " "
bolFileFound = True
End If
objTextStream.Close
Next
[הרקורסיה: לכל תת ספרייה בספרייה הנוכחית, נריץ עליה את פונקציית החיפוש]
For Each objSubFolder in objFolder.SubFolders
Search objSubFolder
Next
End Function
| הערה:
בכדי לאפשר ל-FSO לפתוח קבצים, יש לתת לו את הנתיב האקטואלי ולא את הנתיב של השרת,
C:inetpubwwwroot empindex.htm ולא www.asp.org.il/temp/index.htm לדוגמא:
בכדי לדעת מהו הנתיב האקטואלי של הספרייה בה אנו נמצאים, נשתמש ב Server.MapPath("שם הקובץ")
שם הקובץ בדוגמא שלנו יהיה: index.htm
|
הקוד שכתבנו למעלה ירוץ ויעבור בכל התת-ספריות מתחת לספרייה אותה נגדיר, שבמקרה שלנו יהיה נתיב השורש.
ואז אנו נפתח כל קובץ בתקייה, נבדוק אם המחרוזת הרצויה נמצאת בקובץ ונציג קישור לקובץ במידה ומצאנו את המחרוזת בקובץ.
הערה:
יש לשים לב שככל שמספר הקבצים והתת-ספריות גדל, יגדל גם הזמן שיקח לבצע את החיפוש.
אם עליך לבצע חיפוש מסיבי, עדיף שבמקום להשתמש בקוד שכתבנו, תשתמש במשהו אחר כדוגמת: Microsofts Index Server
|
ניהול התוכן בעזרת FSO
עד כה, טעמתם חלק חשוב מה-FSO, מאפייניו ושיטותיו. בואו ונחפור טיפה יותר עמוק ונעשה קצת עיצוב הנדסי ונתקל בבעיות קשות יותר. :)
ניהול התוכן, או באנגלית: Content Managment, מאפשר לנו לשמור, לשנות ולהפעיל משימות על התכנים של הקבצים. ניהול חכם של התוכן עושה זאת בקלות וללא כאב.
מאחורי הקלעים של אפלקצייה כבדה, יש משחק רק עם הקבצים והתוכן שלהם. כאן שוב נכנס ה-FSO. אנו צריכים להעביר, להעתיק, למחוק, לשנות וליצור קבצים. וכאן, חברנו FSO נכנס בגאווה.
בחלקו העליון של המאמר דנו למערכת המאפשרת הרשמת סופרים ופרסום תכניהם. מה שלא הזכרנו זה מה בדיוק עושים עם הקובץ.
דבר ראשון, קרוב לודאי שתרצה לשנות את שם הקובץ, מכיון שהסופר בוודאי קרא לקובץ בשם אותו הוא מבין ומסמל לו משהו. מכיוון שעכשיו הקובץ אצלנו וברצוננו לעקוב אחר כל המסמכים, נרצה לשנות את שמות המסמכים למשהו יחודי, אשר יזוהה בקלות ע"י המערכת.
לצערנו, FSO לא מאפשר שינוי שמות קבצים בצורה פשוטה, אז נצטרך להנדס קצת:
<%
[יצירת אובייקט ה-FSO]
set fso = Server.Createobject("Scripting.FileSystemObject")
path = "c: emp est.txt"
strDate = Replace(Date(), "/", "")
strDir = "c:inetpubwwwrootarticles" & strDate
strNewFileName = Hour(Now) & "_" & Minute(Now) & "_" &
second(Now) & ".html"
[פתיחת הקובת הישן]
set file = fso.opentextfile(path, 1) <-- לקריאה בלבד
strText = file.readall
set file = nothing
[בדיקה אם קיימת הספרייה ויצירתה אם אינה קיימת]
if not fso.folderexists(Server.MapPath(strDir)) then
set f = fso.CreateFolder(Server.MapPath(strDir))
else
set f = fso.GetFolder(Server.MapPath(strDir))
end if
[יצירה וכתיבה של קובץ חדש]
set file = fso.Createtextfile(f.path & "" & strNewFileName)
file.write(strText)
set f = nothing
file.close
set file = nothing
[מחיקת הקובץ הישן
fso.DeleteFile(path & "" & rst("FileName") & i)
[נקיון]
set fso = nothing
%>
המחסור ביכולות של FSO יכול לשמש לנו כיתרון בדוגמא זו, אנו יכולים לבצע שני מהלכים בפעם אחת.
דבר ראשון, נפתח ונקרא את התוכן של הקובץ. אני מניח שנרצה ליצור ספרייה מיוחדת וגם לתת שם מיוחד למסמך. אך מכיוון שכל פעם הנתיב של הספרייה ישתנה, עלינו לבדוק תחילה אם קיימת כבר ספרייה כזו, ובמידה ולא, ניצור אחת.
פעולה זו נעשית בעזרת המשפט: if not fso.FolderExists
אחר כך, נשיג את הנתיב הרצוי של הספרייה החדשה וניצור בו את הקובץ החדש בשם אותו אנו נבחר. (אסור לשכוח ש-FSO צריך לדעת מהו הנתיב המלא בכדי לשחק עם הקבצים והספריות.)
לאחר שסיימנו עם הקובץ החדש, נרצה להיפטר מהקובץ הישן כדי שלא יתפוס סתם מקום במערכת. מחיקה נעשית בעזרת שיטת DeleteFile.
אז שני המהלכים אותם ביצענו כאן היו שינוי שם הקובץ והעברתו לספרייה משלנו.
אל לנו לשכוח שיכלנו בקלות להמשיך ושחק עם התוחכן של הקובץ לפני שכתבנו אותו לקובץ החדש.
מה אינך יכול לעשות?
ל-FSO ישנן מספר חולשות. הוא לא יודע לעבוד עם קבצים בינארים. זה כולל מסמכי וורד, סוגים רבים של קבצי תמונות, ולצערנו, סוגים רבים של קבצים אחרים. למרות זאת עדיין ניתן להעביר את אותם קבצים, למחוק אותם וכו...
מה שאינך יכול לעשות הוא לפתוח את אותם קבצים.
מגבלה נוספת היא גודל הקובץ. כאשר אתה קורא או כותב תוכן רב בבת אחת, כל המידע נשמר בזכרון וככל שגודל התוכן גדל, הגודל שזה תופס בזכרון גדל בהתאם. דבר זה גורם להאטה כללית ולכן, במידה ואתה רוצה לערוך קבצים גדולים או אלפי קבצים קטנים, קח בחשבון שכדאי לפעמים לחלק את הקובץ לחלקים קטנים יותר ולנקות את הזכרון לעיתים קרובות. (לתת למשתנים ערך NULL או "" ושחרור האובייקטים.) שיטה נוספת לייעול מסיבי של העבודה עם הקבצים היא הסבת האלפיקציה לאובייקט COM.
בעזרת FSO ניתן אף לנהל הרשאות ומאפייני קבצים. דרך מצויינת לשמירה על האבטחה היא ליצור את אותו ספר אורחים שתארנו קודם כאשר הקובץ מוגדר כקריאה בלבד, ואז, לשנות את מאפייני הקובץ לכתיבה רק כאשר צריך להוסיף מישהו לקובץ ומיד להחזיר אותו למצב של קריאה בלבד ברגע שאנו מסיימים את ההוספה לקובץ. בשיטה זו משתמשים לרוב בסקריפטים של CGI וב-PERL, אך לצערנו, אין דרך נוחה לעשות זו בעזרת FSO.
מה אתה כן יכול לעשות?
ישנן אפשרויות מדליקות לדברים שניתן לעשות בעזרת FSO ומתכנתים רבים לא מודעים להם בכלל. אלו אפשרויות שבדרך כלל אתה מוצא אותן אחרי שכבר עשית את הדברים בדרך הקשה, ואתה אז אומר לעצמך: "אילו רק ידעתי על זה קודם!"
ניסקור כאן מספר אפשרויות FSO לא שכיחות:
| שיטות לא שכיחות |
| GetSpecialFolder |
מחזיר את הנתיב של הספריות המיוחדות של מערכת חלונות: ספריית ההתקנות, ספריית ה-SYSTEM וספריית ה-TEMP.
צורת כתיבה: FSO.GetSpecialFolder([0, 1, or 2]) |
| GetTempName |
מחזיר שם קובץ זמני או תקייה באקראיות. (שימושי כאשר יש הגבלה של גודל קובץ, כמו שכתבנו למעלה) |
| GetAbsolutePathName |
מחזיר את הנתיב האבסולוטי (כמו Server.MapPath) לדוגמא:
FSO.GetAbsolutePathName("region") יחזיר משהו כמו: "c:mydocsmyfolder
egion" |
| GetExtensionName |
מחזיר את הסיומת (סוג קובץ) של האובייקט האחרון בנתיב, לדוגמא:
FSO.GetExtensionName("c:docs est.txt") יחזיר txt
|
| GetBaseName and GetParentFolder |
מחזיר את הספרייה הבסיסית ואת ספריית האב של האובייקט האחרון בנתיב, לדוגמא:
FSO.GetParentFolder ("c:docsmydocs") יחזיר docs
|
| Drives Property |
מחזיר אוסף של כל הכוננים הקיימים במחשב. זה שימושי אם אתה רוצה לבנות מעין אקספלורר |
מומלץ לכתוב את הקוד תחת השגחה צמודה ודיבאגינג רציני כי הפונקציות למעלה יתנו לך שגיאות מגעילות אם יתקלו בקבצים או ספריות שאינם קיימים.
מסקנות
כמו שניתן להבין מהמאר הזה, FSO הוא אובייקט חזק מאוד ושימושי ביותר ואנו רק נגענו בו בקצה המזלג. אתרים גדולים רבים משתמשים באפשרויות אותן מאפשר ה-FSO ורבים מהם משלמים כסף רב לעשות זאת. כל זמן זה, קיים ה-FSO ומחכה שמישהו יבוא וישתמש בכוחו בתבונה!
כעת, כשיש בידכם מעט מהידע החשוב הזה, צאו ובנו אפליקציות חזקות ואפילו תשתמשו בו לדברים פשוטים יותר כגון הספר אורחים עליו לא הפסקנו לכתוב...
בהצלחה...
|