-
כיצד אני מאתר סיומת קובץ מקומי במחשב
או בניסוח אחר - כיצד אני פותח קובץ מקומי במחשב - שאני יודע את שם הקובץ, ללא הסיומתמה אני מנסה לעשות?
יש לי טבלה שאני מאפשר לצרף לכל שורה, מסמך בודד מאחד מסוגי סיומות הקבציםדוגמא:
OpenFileDialog הוספתחוזה = new OpenFileDialog(); הוספתחוזה.Filter = "contract Files|*.pdf;*.jpg;*.jpeg"; string סיומתקובץ = Path.GetExtension(הוספתחוזה.FileName); string נתיביבואהוספתחוזה = הוספתחוזה.FileName; string path = Directory.GetCurrentDirectory(); if (!Directory.Exists(path + "\\contract")) Directory.CreateDirectory(path + "\\contract"); File.Copy(נתיביבואהוספתחוזה, path + "\\contract" + "\\" + מזההרשומה + סיומתקובץ, true);
ואני מעוניין באפשרות לפתוח בצורה ישירה את הקובץ
הדרך שאני מכיר זה:System.Diagnostics.Process.Start(path + "\\contract" + "\\" + מזההרשומה + ".pdf");
איפה הסתבכתי?
בדרך הזו
חובה לציין בנוסף לשם הקובץ (המקבל ערך ידוע) את סיומת הקובץ
(שימוש ב* החזיר שגיאה)
שאיננה ידועה לי - היות וכאמור ניתן לצרף ממספר סיומותניסתי להשתמש במתודה Path.GetExtension
ללא הצלחהאשמח לעזרתכם
-
GetExtension מקבל נתיב כולל הסיומת לקובץ ומחזיר את הסיומת שלו.
בעיקרון מה שתעשה זה Directory.EnumerateFiles כדי למצוא את הקובץ שלך.Directory.EnumerateFiles(Path.GetDirectoryName(הנתיב_ללא_הסיומת)).Where(f => f.StartsWith(הנתיב_ללא_הסיומת)).FirstOrDefault()
במקרה ויש לך כמה קבצים עם אותו שם וסיומת שונה, הוא יחזיר את הראשון, במידה ואין בכלל קובץ כזה, הוא יחזיר null.
-
@חגי אני משפר את דיוק הקוד שלך למנוע התאמה של קובץ אחר ששמו מתחיל אותו דבר (רשומה 780 תתאים גם לרשומה 7805):
string fileFromName(string fileWithoutExt) { var name = Path.GetFileName(fileWithoutExt); return Directory.EnumerateFiles(Path.GetDirectoryName(fileWithoutExt)).FirstOrDefault(f => Path.GetFileNameWithoutExtension(f) == name); }
נ.ב. זה מהlinqpad
-
@mekev עוד הערות:
-
אין צורך לבדוק אם תיקיה קיימת. המתודה Directory.CreateDirectory בודקת את זה ובמקרה ויש היא פשוט לא עושה כלום.
-
Directory.GetCurrentDirectory() לא נחוץ. אתה יכול ישר לתת שם יחסי וההתחלה תהיה הCurrentDirectory, כלומר שני הקודים הבאים זהים:
string originalPath = selectedFile.FileName; string path = Directory.GetCurrentDirectory(); Directory.CreateDirectory(path + "\\contract"); File.Copy(originalPath, path + "\\contract" + "\\" + idRow + fileExt, true);
ובלי:
string originalPath = selectedFile.FileName; Directory.CreateDirectory("contract"); File.Copy(originalPath, "contract" + "\\" + idRow + fileExt, true);
שים לב שבקוד השני הנתיב מתחיל ישירות מהמילה contract ללא פתיחה של "\". זה נקרא נתיב יחסי והוא מחושבן תמיד ביחס לCurrentDirectory.
על הקטע של העברית אני לא חוזר, רק מחזק את ידיך לגמור עם זה כמה שיותר מהר.
-
-
@חגי אמר בשליפת סיומת קובץ - לפי שם הקובץ (C#):
במקרה ויש לך כמה קבצים עם אותו שם וסיומת שונה, הוא יחזיר את הראשון
היות ואני מאפשר למשתמש להוסיף מספר סיומות
בתוצאה הזאת הוא שולף ראשון את ה.JPG (לפני הPDF)בעוד אני מעוניין שהמשתמש יראה את הקובץ האחרון שנוצר
(בהנחה שהמשתמש צירף בהתחלה טיוטה בסיומת JPG ואת הקובץ הסופי בPDF, הקובץ המקורי לא נדרס אלא התווסף קובץ נוסף
ותמיד יוצג הטיוטה בסיומת .JPG)האם יש אפשרות לעשות מניפולציה באמצעות File.GetCreationTime להצגת הקובץ האחרון שנוצר?
-
@mekev אתה שם לב כמה אתה מסתבך?
מה הבעיה להוסיף שדה של שם קובץ בכל רשומה, עם הסיומת והכל?עריכה למקרה שתתעקש:
string fileFromName(string fileWithoutExt) { var name = Path.GetFileName(fileWithoutExt); return new DirectoryInfo(Path.GetDirectoryName(fileWithoutExt)) .EnumerateFiles() .OrderByDescending(f => f.CreationTime) .FirstOrDefault(f => Path.GetFileNameWithoutExtension(f.Name) == name)?.FullName; }
-
@dovid אמר בשליפת סיומת קובץ - לפי שם הקובץ (C#):
מה הבעיה להוסיף שדה של שם קובץ בכל רשומה, עם הסיומת והכל?
במידה וניתן להשיג את התוצאה הרצויה בריצה פשוטה של הקוד
מדוע לשמור סתם נתון בבסיס הנתוניםאני הרי לא שומר את הקובץ עצמו במסד
אלא רק נתון סטטי מקומי המפנה לשם/מיקום הקובץ -
@mekev הואיל ודוד לא ענה, אני מרשה לעצמי לדחוף את האף:
במידה וניתן להשיג את התוצאה הרצויה בריצה פשוטה של הקוד
מדוע לשמור סתם נתון בבסיס הנתוניםזה פשוט ענין של גישה יותר בריאה.
באופן כללי, תמיד עדיף לשמור נתון סטטי מאשר לחשבן אותו בכל פעם מחדש, מכמה סיבות:- הרי תמיד תקבל את אותה התוצאה, מה הטעם לחשבן את זה שוב ושוב?
- מקום אחסון תמיד יותר זול מכח חישוב, אתה מנסה לחסוך כמה תוים בודדים בזיכרון, אבל מקריב בשביל כך הרבה משאבים במעבד ובדיסק, ההפסד שלך מרובה מהרווח שלך.
- והכי חשוב: הקוד שלך יהיה יותר פשוט, ויותר מובן, וממילא תחסוך לך זמן יקר בתחזוקה שלו בעתיד.
-
@OdedDvir לא מסכים איתך שזה כלל שאחסון עדיף מחשבון, הייתי מבכר חשבון ברמה זו כשהוא לא מתנגש עם סיבה 3 - סיבוך בקוד או בהנתהגות.
@mekev יש הבדל בין לדעת לבין להסיק. אם לכל רשומה היה קובץ כשמה, זה היה בסדר. הבעיה שישנה סיומת. הסיומת עצמה אפשר למצוא אותה, אבל זה "היסק" זהיר שמביא הנחות סמויות וקוד רגיש יחסית שנוסף על כל הקוד שעליך לתחזק ולהבין. לפחות שמור את הסיומת.
תחשוב בריא, נניח תרצה לאפשר שני קבצים בעתיד, בגישה כעת תצטרך לערוך שינויים מקיפים בשביל כך. או תחשוב שתוכנת שחזור/גיבוי גורם אחר יעתיק את הקבצים מחדש, התאריך האחרון כבר לא יהיה באמת תאריך אחרון. קוראים לזה הנחות מסוכנות, וצריך תמיד לזהות אותם. מה שלא שחור לבן, לברוח. -
@dovid אמר בשליפת סיומת קובץ - לפי שם הקובץ (C#):
יש הבדל בין לדעת לבין להסיק
כלל גדול
החכמתי.לגבי הנקודה האם להעדיף מקום אחסון על פני כח חישוב
יצאתי מתוך הנחה (ללא מקור) שהיות שגם במקום אחסון אני צריך פעולת חישוב לשליפה>הרצת הקובץ(שגם מצריכה חישוב, היות והקובץ אצלי נשמר בתיקיית התוכנה, ויש מספר משתמשים שמחוברים דרך תיקיית רשת כאשר האות כונן לחלקם שונה, אז אוכל לשמור רק את שם הקובץ והסיומת ללא הנתיב המלא )
אז למה לא לעשות ישירות רק את פעולת החישוב?
וע"ז תשובת @dovid סדרה לי את הראש
-