עבור לתוכן

עזרה עם חיפוש בקובץ CSV ממויין (C#)

Featured Replies

פורסם

שלום,

לצורך תוכנית כלשהי עלי לכתוב פרוצדורה שתבצע חיפש של נתון מסויים בקובץ CSV (קובץ די גדול) ותחזיר StreamReader לאותה רשומה(אם קיימת רשומה עם נתון זהה)או לרשומה הקרובה ביותר(הקרובה מלמטה) (הקובץ ממויין).

לדוגמא אם הקובץ הוא:

time, value

1,30

21,34

41,37

52,6

64,54

76,73

88,5

94,2

(השורה הראשונה הכוללת את שמות העמודות היא חלק מהקובץ)

החיפוש יתבצע תמיד עפ"י העמודה הממויינת time.

לדוגמא:

אם הפרוצדורה תקבל 41, היא תחזיר StreamReader שמצביע לתחילת השורה הרביעית.

אם הפרוצדורה תקבל 65, היא תחזיר StreamReader שמצביע לתחילת השורה השביעית - השורה עם הערך time הכי קרוב מלמטה.

עד עכשיו ניסיתי לממש זאת באמצעות חיפוש בינארי, אך זאת בעייה מפני שהפונקציה seek של ה-StreamReader מסרבת לבצע את תפקידה (גם עם שימוש ב-DiscardBufferData). היא פשוט לא תמיד מזיזה את המצביע של הקובץ (עבור קבצים מסויימים כן, עבור אחרים - לא)

למישהו יש רעיון איך לבצע זאת בצורה יעילה?

ד"א אני משתמש ב-C#

פורסם

באופן מסורתי, פעולות SEEK לא עובדות כל כך טוב על קבצים שפתוחים ב-text mode.

אני לא יודע איך זה משתקף ב-C#. אולי הדרך הכי טובה היא לוותר על ה-seek ולהחזיק פשוט שני reader-ים על אותו קובץ, ולקדם את השני רק אחרי שהראשון קבע שהשורה אינה זו שאתה מחפש?

פורסם
  • מחבר

ראשית תודה על התגובה.

לא הבנתי מהי כוונתך להשתמש בשני reader-ים ולקדם את השני רק אחרי שהראשון קבע שהשורה אינה זו שאני מחפש. אני לא מבצע חיפוש סדרתי.

את החיפוש ביצעתי באמצעות קפיצה למקומות שונים בקובץ (עם seek אשר עובדת בבתים):

החזקתי שלושה long-ים :

upper - המיקום העליון בקובץ (בהתחלה מקבל 0)

lower - המיקום התחתון בקובץ (בהתחלה מקבל את כמות הבתים בקובץ)

middle - שהוא (upper+lower) חלקי 2

את upper ו-lower אני משנה בכל פעם עפ"י הרשומה השלמה הקרובה ביותר ל-middle

אך כמו שאמרתי, הקפיצה בתוך הקובץ לא תמיד מתרחשת עקב מתודת ה-seek הקלוקלת.

פורסם

אה, חיפוש בינארי.

טוב אולי מישהו פה שמכיר C# יכול לעזור.

פורסם

הSEEK עובד רק אם הוא מקבל את המידע הנכון (תוצאה של READ)

הנה רעיון - לשמור את הנקודות בקובץ (לא כזה משתלם לקובץ שלך, אגב. עדיף לשמור בזיכרון אולי ?)

http://forums.devx.com/showthread.php?t=155258

פורסם
  • מחבר

תודה shmel.

שאלה נוספת: עד כמה השימוש ב-DiscardBufferedData פוגע בביצועים? אם אני מבצע חיפוש בינארי עלי להשתמש במתודה זו די הרבה (לפני כל פעולת Seek). האם הביצועים שייגרמו עקב כך יהיו כל כך ירודים עד שעדיף יהיה לבצע חיפוש סדרתי בקובץ במקום?

לדברי ה-MSDN:

"Because this method can cause slower performance, use it sparingly and only when you need it for a specific scenario."

פורסם

למה שלא תמדוד את הביצועים בשיטה א לעומת שיטה ב?

פורסם
  • מחבר

מפני שהמימוש שלי לחיפוש בינארי לא תמיד עובד (בעיה עם המתודה seek עבור חלק מהקבצים), אז אני מתלבט אם להשקיע זמן בלנסות לתקן אותו או לכתוב מתודה שתעשה זאת בחיפוש סדרתי.

פורסם

:silly:

כתוב מתודה שתעשה את זה בחיפוש סדרתי, ותחיה עם התוצאות, כי האופציה למימוש בינארי אצלך לא באמת קיימת אם היא לא עובדת עבור חלק מהקבצים.

פורסם
  • מחבר

זאת באמת האופצייה שאני נוטה אליה, אך אני חושש מפני שהקבצים שהתוכנית תצטרך לעבד יהיו באמת גדולים (מאות אלפי רשומות).

פורסם

בכל מקרה הכי טוב באמת זה למדוד את הביצועים במימוש פשוט, ולראות אם הם מספיק טובים.

אבל...

:silly:

כתוב מתודה שתעשה את זה בחיפוש סדרתי, ותחיה עם התוצאות, כי האופציה למימוש בינארי אצלך לא באמת קיימת אם היא לא עובדת עבור חלק מהקבצים.

לי זה נשמע מגוחך מה ש-shmel אומר. זה כאילו שהוא אומר שאי אפשר לממש ב-C# חיפוש בינארי בקובץ.

אני באמת לא מכיר את C# מספיק טוב אבל קשה לי להאמין שאי אפשר לעשות משהו כזה בסיסי.

האם מדובר במשימה חד פעמית, שממש לא חשוב הביצועים של הפתרון?

אלא אם כן הזמן שלך הרבה יותר יקר מהצורך בביצועים (אל תשכח למדוד), אני ממליץ שתמצא את הבעיה ותפתור אותה, או שתעשה את אותו אלגוריתם בשיטה אחרת (אולי ממשק יותר Low level לקבצים?). חוץ מזה אולי תלמד משהו חדש.

פורסם

בעיקרון - אם הם "אינסופיים" (לצורך העיניין, אם יש לך הרבה נתונים אתה בכל מקרה בבעיה) - מיהו ה LEAST EVIL שעובד ?

במונחים של C# זו בעיה - כי אתה לא באמת יודע איך הדברים עובדים. הגישה האמפירית (לכתוב 2 שיטות ולבדוק איזו עובדת יותר טוב) היא חוק אצבע טוב. זו אכן שאלה של צורך. לגבי הצורך אני מחזק את הנקודה - אם עבור חלק מהקבצים הקוד לא עובד - או שתשתמש במשהו אחר, או שתתקן את הקבצים. אגב אם בביצועים עסקינן - תפרנה לשפות יותר בסיסיות (כמו C וC++) במקום להשתמש באובייקטים שאתה לא יודע ב10000000% מה הם עושים (C.NET# וJAVA)

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים