powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Записать в текстовый файл построчно.
32 сообщений из 32, показаны все 2 страниц
Записать в текстовый файл построчно.
    #38676482
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Создаю объект
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
 class IniRecord : IComparable<IniRecord>
    {
        public string Section { get; set; }
        public List<string> KeysVals { get; set; }
        //public List<string> Keys;
        //public List<string> Values;

        public IniRecord()
        {
            KeysVals = new List<string>();
        }

        public IniRecord(string sect)
        {
            Section = sect;
            KeysVals = new List<string>();
        }

        public int CompareTo(IniRecord compare_rec)
        {
            // A null value means that this object is greater. 
            if (compare_rec == null)
                return 1;

            else
                return this.Section.CompareTo(compare_rec.Section);
        }
    }


заполняю лист объектов
Код: c#
1.
2.
  List<IniRecord> records = ini_parser.LoadIniFileToStructure();
  records.Sort();


Теперь хочу записать в текстовый файл
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  File.WriteAllText(@"C:\DMP\test.ini", String.Empty);
  foreach (IniRecord rec in records)
  {
       File.AppendAllText(@"C:\DMP\test.ini", rec.Section + "\n\r");
       if (rec.KeysVals.Count > 0)
       {
           foreach (string str  in rec.KeysVals)
               File.AppendAllText(@"C:\DMP\test.ini", str + "\n\r");
       }
  }


проблема что эта па... нехороший класс записывает все в одну строку а не построчно. Перепробовал все методы - один х... результат.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676484
Фотография Нахлобуч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"\r\n" или "Environment.NewLine"
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676492
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нахлобуч"\r\n" или "Environment.NewLine"

точно! спасибо!
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676497
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7, про перевод строки Нахлобуч уже ответил. Советую теперь задуматься над оптимальностью работы с файлом. Ты вызываешь в цикле File.AppendAllText() которая открывает файл, записывает данные и закрывает файл. Это крайне не оптимально. Лучше открыть файл ровно один раз.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
using (FileStream fileStream = new FileStream(@"C:\DMP\test.ini", FileMode.Create, FileAccess.Write, FileShare.None))
using (StreamWriter w = new StreamWriter(fileStream))
{
	foreach (IniRecord rec in records)
	{
		w.WriteLine(rec.Section);
		if (rec.KeysVals.Count > 0)
		{
			foreach (string str  in rec.KeysVals)
			{
				w.WriteLine(str);
			}
		}
	}   
}


Также получаем полезный побочный эффект. Использование функции WriteLine() избавляет нас от забот с переводом строки.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676498
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лучше прибраться через StringBuilder,
if (rec.KeysVals.Count > 0) - избыточно..,
проверку посадить выше на секцию, или секцию посадить на контракт.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676504
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bazile, Где-то в степи
спасибо за подсказки, переписал.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676505
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
фрагмент
Код: c#
1.
 foreach (string str  in rec.KeysVals)


можно заменить, если скрестить Нахлобуча и Shocker.Pro :)) 16199787
Код: c#
1.
StringBuilder.Append(string.Concat(string.Join(Environment.NewLine, rec.KeysVals), Environment.NewLine));
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676508
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Где-то в степифрагмент
Код: c#
1.
 foreach (string str  in rec.KeysVals)


можно заменить, если скрестить Нахлобуча и Shocker.Pro :)) 16199787
Код: c#
1.
StringBuilder.Append(string.Concat(string.Join(Environment.NewLine, rec.KeysVals), Environment.NewLine));



если сравнить
Код: c#
1.
2.
foreach (string str in rec.KeysVals)
    sw.WriteLine(str);


и
Код: c#
1.
StringBuilder.Append(string.Concat(string.Join(Environment.NewLine, rec.KeysVals), Environment.NewLine));



то, по крайней мере визуально, второй вариант берет больше действий. :)
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676521
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7,
тут надо быть конченым циником, что бы понять всю тонкость :))
да и по всей логике предложного кода, допускается ли секция as null, допускается ли KeysVals as !Any
если нет - то надо на период разработки внести отлов - откуда прет фуфло..
если допускается, то очистить код можно
foreach (IniRecord rec in records.Where(a=>a.Section!=null&&a.KeysVals.Any()))
да и вообще, там пара ключ - значение, наверное лучше хранить все это хозяйство в словаре?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676522
Фотография Ken@t
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А нахуа Ini ? Что бы было как -то совместимо, других мотиваций не наблюдаю?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676525
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ken@t,
Ну может ностальгия...
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38676533
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ken@tА нахуа Ini ? Что бы было как -то совместимо, других мотиваций не наблюдаю?
просто, надежно и потом такие монстры как LabView, TestStand почему то от ini не отказываются.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38677187
VIT2708
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7,

Самый простой способ

Код: c#
1.
System.IO.File.WriteAllLines(fileName, records.ToArray());
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38677213
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VIT2708, самый простой способ получить ошибку компиляции ты хотел сказать - Cannot convert from IniRecord[] to string[]
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38677220
VIT2708
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileVIT2708, самый простой способ получить ошибку компиляции ты хотел сказать - Cannot convert from IniRecord[] to string[]

Автор использует List
Код: c#
1.
List<IniRecord>

List запросто конвертируется в масив
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38677306
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VIT2708, метод WriteAllLines принимает массив строк. Ты пытаешься передать массив IniRecord. Соответственно будет ошибка компиляции. Если ты ожидал, что метод ToArray() вызовет ToString() для всех элементов массива, то он этого не делает. И даже если бы и делал, то результат все равно был бы неправильный т.к. в классе IniRecord нет реализации ToString().
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38677324
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazile,
ну это можно как экспромт сделать, переопределить метод ToString() as

[section]
key = value
.........
Тогда да, можно исполнить весь этот код одной строчкой с фильтрами и тд.
Можно без, вернуть массив строк как единица секции..
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38677396
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть же на CodeProject импортированные функции, которые позволяют работать с Ini привычным образом. Зачем велосипед?

Код класса, взятый из http://www.codeproject.com/Articles/20053/A-Complete-Win-INI-File-Utility-Class
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
    /// <summary>
    /// Provides methods for reading and writing to an INI file.
    /// </summary>
    public class IniFile
    {
        #region Constants

        /// <summary>
        /// The maximum size of a section in an ini file.
        /// </summary>
        /// <remarks>
        /// This property defines the maximum size of the buffers 
        /// used to retreive data from an ini file.  This value is 
        /// the maximum allowed by the win32 functions 
        /// GetPrivateProfileSectionNames() or 
        /// GetPrivateProfileString().
        /// </remarks>
        public const int MAX_SECTION_SIZE = 32767; // 32 KB 

        #endregion

        #region P/Invoke declares

        /// <summary>
        /// A static class that provides the win32 P/Invoke signatures 
        /// used by this class.
        /// </summary>
        /// <remarks>
        /// Note:  In each of the declarations below, we explicitly set CharSet to 
        /// Auto.  By default in C#, CharSet is set to Ansi, which reduces 
        /// performance on windows 2000 and above due to needing to convert strings
        /// from Unicode (the native format for all .Net strings) to Ansi before 
        /// marshalling.  Using Auto lets the marshaller select the Unicode version of 
        /// these functions when available.
        /// </remarks>
        [System.Security.SuppressUnmanagedCodeSecurity]
        private static class NativeMethods
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileSectionNames
                (IntPtr lpszReturnBuffer,
                 uint nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetPrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpDefault,
                 StringBuilder lpReturnedString,
                 int nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetPrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpDefault,
                 [In, Out] char[] lpReturnedString,
                 int nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpDefault,
                 IntPtr lpReturnedString,
                 uint nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileInt
                (string lpAppName,
                 string lpKeyName,
                 int lpDefault,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileSection
                (string lpAppName,
                 IntPtr lpReturnedString,
                 uint nSize,
                 string lpFileName);

            //We explicitly enable the SetLastError attribute here because
            // WritePrivateProfileString returns errors via SetLastError.
            // Failure to set this can result in errors being lost during 
            // the marshal back to managed code.
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool WritePrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpString,
                 string lpFileName);


        }

        #endregion

        #region Properies
        
        /// <summary>
        /// Initializes a new instance of the <see cref="IniFile"/> class.
        /// </summary>
        /// <param name="path">The ini file to read and write from.</param>
        public IniFile(string path)
        {
            //Convert to the full path.  Because of backward compatibility, 
            // the win32 functions tend to assume the path should be the 
            // root Windows directory if it is not specified.  By calling 
            // GetFullPath, we make sure we are always passing the full path
            // the win32 functions.
            Path = System.IO.Path.GetFullPath(path);
        }

        /// <summary>
        /// Gets the full path of ini file this object instance is operating on.
        /// </summary>
        /// <value>A file path.</value>
        public string Path { get; private set; } 

        #endregion

        #region Get Value Methods

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.String"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/></returns>
        /// <remarks>
        /// The retreived value must be less than 32KB in length.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public string GetString(string sectionName,
                                string keyName,
                                string defaultValue)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            StringBuilder retval = new StringBuilder(IniFile.MAX_SECTION_SIZE);

            NativeMethods.GetPrivateProfileString(sectionName, 
                                                  keyName, 
                                                  defaultValue, 
                                                  retval,
                                                  IniFile.MAX_SECTION_SIZE, 
                                                  Path);

            return retval.ToString();
        }

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.Int16"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public int GetInt16(string sectionName,
                            string keyName,
                            short  defaultValue)
        {
            int retval = GetInt32(sectionName, keyName, defaultValue);

            return Convert.ToInt16(retval);
        }

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.Int32"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/></returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public int GetInt32(string sectionName,
                            string keyName,
                            int defaultValue)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            
            return NativeMethods.GetPrivateProfileInt(sectionName, keyName, defaultValue, Path);
        }

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.Double"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/></returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public double GetDouble(string sectionName,
                                string keyName,
                                double defaultValue)
        {
            string _retval = GetString(sectionName, keyName, "");
            return string.IsNullOrEmpty(_retval) 
                ? defaultValue 
                : Convert.ToDouble(_retval, CultureInfo.InvariantCulture);
        }

        #endregion

        #region GetSectionValues Methods

        /// <summary>
        /// Gets all of the values in a section as a list.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to retrieve values from.
        /// </param>
        /// <returns>
        /// A <see cref="List{T}"/> containing <see cref="KeyValuePair{T1, T2}"/> objects 
        /// that describe this section.  Use this verison if a section may contain
        /// multiple items with the same key value.  If you know that a section 
        /// cannot contain multiple values with the same key name or you don't 
        /// care about the duplicates, use the more convenient 
        /// <see cref="GetSectionValues"/> function.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference  (Nothing in VB)
        /// </exception>
        public List<KeyValuePair<string, string>> GetSectionValuesAsList(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            string[] _keyValuePairs = null;

            //Allocate a buffer for the returned section names.
            IntPtr _ptr = Marshal.AllocCoTaskMem(MAX_SECTION_SIZE);
            try
            {
                //Get the section key/value pairs into the buffer.
                int _len = NativeMethods.GetPrivateProfileSection(
                    sectionName,
                    _ptr,
                    MAX_SECTION_SIZE,
                    Path);

                _keyValuePairs = ConvertNullSeperatedStringToStringArray(_ptr, _len);
            }
            finally
            {
                //Free the buffer
                Marshal.FreeCoTaskMem(_ptr);
            }

            //Parse keyValue pairs and add them to the list.
            List<KeyValuePair<string, string>> _retval = new List<KeyValuePair<string, string>>(
                from _t in _keyValuePairs
                let _equalSignPos = _t.IndexOf('=')
                let _key = _t.Substring(0, _equalSignPos)
                let _value = _t.Substring(_equalSignPos + 1, _t.Length - _equalSignPos - 1)
                select new KeyValuePair<string, string>(_key, _value));

            return _retval;
        }

        /// <summary>
        /// Gets all of the values in a section as a dictionary.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to retrieve values from.
        /// </param>
        /// <returns>
        /// A <see cref="Dictionary{T, T}"/> containing the key/value 
        /// pairs found in this section.  
        /// </returns>
        /// <remarks>
        /// If a section contains more than one key with the same name, 
        /// this function only returns the first instance.  If you need to 
        /// get all key/value pairs within a section even when keys have the 
        /// same name, use <see cref="GetSectionValuesAsList"/>.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference  (Nothing in VB)
        /// </exception>
        public Dictionary<string, string> GetSectionValues(string sectionName)
        {
            return GetSectionValuesAsList(sectionName).ToDictionary(p => p.Key, z => z.Value);

            ////Convert list into a dictionary.
            //Dictionary<string, string> _retval = new Dictionary<string, string>(_keyValuePairs.Count);

            //foreach (KeyValuePair<string, string> keyValuePair in _keyValuePairs)
            //{
            //    //Skip any key we have already seen.
            //    if (!_retval.ContainsKey(keyValuePair.Key))
            //    {
            //        _retval.Add(keyValuePair.Key, keyValuePair.Value);
            //    }
            //}

            //return _retval;
        }

        #endregion

        #region Get Key/Section Names

        /// <summary>
        /// Gets the names of all keys under a specific section in the ini file.
        /// </summary>
        /// <param name="sectionName">
        /// The name of the section to read key names from.
        /// </param>
        /// <returns>An array of key names.</returns>
        /// <remarks>
        /// The total length of all key names in the section must be 
        /// less than 32KB in length.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference  (Nothing in VB)
        /// </exception>
        public string[] GetKeyNames(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            string[] _retval;
            
            //Allocate a buffer for the returned section names.
            IntPtr _ptr = Marshal.AllocCoTaskMem(IniFile.MAX_SECTION_SIZE);
            try
            {
                //Get the section names into the buffer.
                int _len = NativeMethods.GetPrivateProfileString(
                    sectionName,
                    null,
                    null,
                    _ptr,
                    MAX_SECTION_SIZE,
                    Path);

                _retval = ConvertNullSeperatedStringToStringArray(_ptr, _len);
            }
            finally
            {
                //Free the buffer
                Marshal.FreeCoTaskMem(_ptr);
            }

            return _retval;
        }

        /// <summary>
        /// Gets the names of all sections in the ini file.
        /// </summary>
        /// <returns>An array of section names.</returns>
        /// <remarks>
        /// The total length of all section names in the section must be 
        /// less than 32KB in length.
        /// </remarks>
        public string[] GetSectionNames()
        {
            string[] _retval;

            //Allocate a buffer for the returned section names.
            IntPtr _ptr = Marshal.AllocCoTaskMem(IniFile.MAX_SECTION_SIZE);
            try
            {
                //Get the section names into the buffer.
                int _len = NativeMethods.GetPrivateProfileSectionNames(_ptr, MAX_SECTION_SIZE, Path);
                _retval = ConvertNullSeperatedStringToStringArray(_ptr, _len);
            }
            finally
            {
                //Free the buffer
                Marshal.FreeCoTaskMem(_ptr);
            }
            
            return _retval;
        }

        /// <summary>
        /// Converts the null seperated pointer to a string into a string array.
        /// </summary>
        /// <param name="ptr">A pointer to string data.</param>
        /// <param name="valLength">
        /// Length of the data pointed to by <paramref name="ptr"/>.
        /// </param>
        /// <returns>
        /// An array of strings; one for each null found in the array of characters pointed
        /// at by <paramref name="ptr"/>.
        /// </returns>
        private static string[] ConvertNullSeperatedStringToStringArray(IntPtr ptr, int valLength)
        {
            string[] _retval = new string[0];

            if (valLength > 0)
            {
                //Convert the buffer into a string.  Decrease the length 
                //by 1 so that we remove the second null off the end.
                string _buff = Marshal.PtrToStringAuto(ptr, valLength - 1);

                //Parse the buffer into an array of strings by searching for nulls.
                _retval = _buff.Split('\0');
            }

            return _retval;
        }

        #endregion

        #region Write Methods

        /// <summary>
        /// Writes a <see cref="T:System.String"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The string value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        private void WriteValueInternal(string sectionName, string keyName, string value)
        {
            if (!NativeMethods.WritePrivateProfileString(sectionName, keyName, value, Path))
                throw new System.ComponentModel.Win32Exception();
        }

        /// <summary>
        /// Writes a <see cref="T:System.String"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The string value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> or 
        /// <paramref name="value"/>  are a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, string value)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            if (value == null)
                throw new ArgumentNullException("value");

            WriteValueInternal(sectionName, keyName, value);
        }

        /// <summary>
        /// Writes an <see cref="T:System.Int16"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        public void WriteValue(string sectionName, string keyName, short value)
        {
            WriteValue(sectionName, keyName, (int)value);
        }

        /// <summary>
        /// Writes an <see cref="T:System.Int32"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, int value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        /// <summary>
        /// Writes an <see cref="T:System.Single"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, float value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        /// <summary>
        /// Writes an <see cref="T:System.Double"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, double value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        #endregion

        #region Delete Methods

        /// <summary>
        /// Deletes the specified key from the specified section.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to remove the key from.
        /// </param>
        /// <param name="keyName">
        /// Name of the key to remove.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void DeleteKey(string sectionName, string keyName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            WriteValueInternal(sectionName, keyName, null);
        }

        /// <summary>
        /// Deletes a section from the ini file.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to delete.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference (Nothing in VB)
        /// </exception>
        public void DeleteSection(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            WriteValueInternal(sectionName, null, null);
        }

        #endregion
    }

...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678383
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arm79Есть же на CodeProject импортированные функции, которые позволяют работать с Ini привычным образом. Зачем велосипед?

Код класса, взятый из http://www.codeproject.com/Articles/20053/A-Complete-Win-INI-File-Utility-Class
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
    /// <summary>
    /// Provides methods for reading and writing to an INI file.
    /// </summary>
    public class IniFile
    {
        #region Constants

        /// <summary>
        /// The maximum size of a section in an ini file.
        /// </summary>
        /// <remarks>
        /// This property defines the maximum size of the buffers 
        /// used to retreive data from an ini file.  This value is 
        /// the maximum allowed by the win32 functions 
        /// GetPrivateProfileSectionNames() or 
        /// GetPrivateProfileString().
        /// </remarks>
        public const int MAX_SECTION_SIZE = 32767; // 32 KB 

        #endregion

        #region P/Invoke declares

        /// <summary>
        /// A static class that provides the win32 P/Invoke signatures 
        /// used by this class.
        /// </summary>
        /// <remarks>
        /// Note:  In each of the declarations below, we explicitly set CharSet to 
        /// Auto.  By default in C#, CharSet is set to Ansi, which reduces 
        /// performance on windows 2000 and above due to needing to convert strings
        /// from Unicode (the native format for all .Net strings) to Ansi before 
        /// marshalling.  Using Auto lets the marshaller select the Unicode version of 
        /// these functions when available.
        /// </remarks>
        [System.Security.SuppressUnmanagedCodeSecurity]
        private static class NativeMethods
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileSectionNames
                (IntPtr lpszReturnBuffer,
                 uint nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetPrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpDefault,
                 StringBuilder lpReturnedString,
                 int nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetPrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpDefault,
                 [In, Out] char[] lpReturnedString,
                 int nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpDefault,
                 IntPtr lpReturnedString,
                 uint nSize,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileInt
                (string lpAppName,
                 string lpKeyName,
                 int lpDefault,
                 string lpFileName);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileSection
                (string lpAppName,
                 IntPtr lpReturnedString,
                 uint nSize,
                 string lpFileName);

            //We explicitly enable the SetLastError attribute here because
            // WritePrivateProfileString returns errors via SetLastError.
            // Failure to set this can result in errors being lost during 
            // the marshal back to managed code.
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool WritePrivateProfileString
                (string lpAppName,
                 string lpKeyName,
                 string lpString,
                 string lpFileName);


        }

        #endregion

        #region Properies
        
        /// <summary>
        /// Initializes a new instance of the <see cref="IniFile"/> class.
        /// </summary>
        /// <param name="path">The ini file to read and write from.</param>
        public IniFile(string path)
        {
            //Convert to the full path.  Because of backward compatibility, 
            // the win32 functions tend to assume the path should be the 
            // root Windows directory if it is not specified.  By calling 
            // GetFullPath, we make sure we are always passing the full path
            // the win32 functions.
            Path = System.IO.Path.GetFullPath(path);
        }

        /// <summary>
        /// Gets the full path of ini file this object instance is operating on.
        /// </summary>
        /// <value>A file path.</value>
        public string Path { get; private set; } 

        #endregion

        #region Get Value Methods

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.String"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/></returns>
        /// <remarks>
        /// The retreived value must be less than 32KB in length.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public string GetString(string sectionName,
                                string keyName,
                                string defaultValue)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            StringBuilder retval = new StringBuilder(IniFile.MAX_SECTION_SIZE);

            NativeMethods.GetPrivateProfileString(sectionName, 
                                                  keyName, 
                                                  defaultValue, 
                                                  retval,
                                                  IniFile.MAX_SECTION_SIZE, 
                                                  Path);

            return retval.ToString();
        }

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.Int16"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public int GetInt16(string sectionName,
                            string keyName,
                            short  defaultValue)
        {
            int retval = GetInt32(sectionName, keyName, defaultValue);

            return Convert.ToInt16(retval);
        }

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.Int32"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/></returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public int GetInt32(string sectionName,
                            string keyName,
                            int defaultValue)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            
            return NativeMethods.GetPrivateProfileInt(sectionName, keyName, defaultValue, Path);
        }

        /// <summary>
        /// Gets the value of a setting in an ini file as a <see cref="T:System.Double"/>.
        /// </summary>
        /// <param name="sectionName">The name of the section to read from.</param>
        /// <param name="keyName">The name of the key in section to read.</param>
        /// <param name="defaultValue">The default value to return if the key
        /// cannot be found.</param>
        /// <returns>The value of the key, if found.  Otherwise, returns 
        /// <paramref name="defaultValue"/></returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public double GetDouble(string sectionName,
                                string keyName,
                                double defaultValue)
        {
            string _retval = GetString(sectionName, keyName, "");
            return string.IsNullOrEmpty(_retval) 
                ? defaultValue 
                : Convert.ToDouble(_retval, CultureInfo.InvariantCulture);
        }

        #endregion

        #region GetSectionValues Methods

        /// <summary>
        /// Gets all of the values in a section as a list.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to retrieve values from.
        /// </param>
        /// <returns>
        /// A <see cref="List{T}"/> containing <see cref="KeyValuePair{T1, T2}"/> objects 
        /// that describe this section.  Use this verison if a section may contain
        /// multiple items with the same key value.  If you know that a section 
        /// cannot contain multiple values with the same key name or you don't 
        /// care about the duplicates, use the more convenient 
        /// <see cref="GetSectionValues"/> function.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference  (Nothing in VB)
        /// </exception>
        public List<KeyValuePair<string, string>> GetSectionValuesAsList(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            string[] _keyValuePairs = null;

            //Allocate a buffer for the returned section names.
            IntPtr _ptr = Marshal.AllocCoTaskMem(MAX_SECTION_SIZE);
            try
            {
                //Get the section key/value pairs into the buffer.
                int _len = NativeMethods.GetPrivateProfileSection(
                    sectionName,
                    _ptr,
                    MAX_SECTION_SIZE,
                    Path);

                _keyValuePairs = ConvertNullSeperatedStringToStringArray(_ptr, _len);
            }
            finally
            {
                //Free the buffer
                Marshal.FreeCoTaskMem(_ptr);
            }

            //Parse keyValue pairs and add them to the list.
            List<KeyValuePair<string, string>> _retval = new List<KeyValuePair<string, string>>(
                from _t in _keyValuePairs
                let _equalSignPos = _t.IndexOf('=')
                let _key = _t.Substring(0, _equalSignPos)
                let _value = _t.Substring(_equalSignPos + 1, _t.Length - _equalSignPos - 1)
                select new KeyValuePair<string, string>(_key, _value));

            return _retval;
        }

        /// <summary>
        /// Gets all of the values in a section as a dictionary.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to retrieve values from.
        /// </param>
        /// <returns>
        /// A <see cref="Dictionary{T, T}"/> containing the key/value 
        /// pairs found in this section.  
        /// </returns>
        /// <remarks>
        /// If a section contains more than one key with the same name, 
        /// this function only returns the first instance.  If you need to 
        /// get all key/value pairs within a section even when keys have the 
        /// same name, use <see cref="GetSectionValuesAsList"/>.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference  (Nothing in VB)
        /// </exception>
        public Dictionary<string, string> GetSectionValues(string sectionName)
        {
            return GetSectionValuesAsList(sectionName).ToDictionary(p => p.Key, z => z.Value);

            ////Convert list into a dictionary.
            //Dictionary<string, string> _retval = new Dictionary<string, string>(_keyValuePairs.Count);

            //foreach (KeyValuePair<string, string> keyValuePair in _keyValuePairs)
            //{
            //    //Skip any key we have already seen.
            //    if (!_retval.ContainsKey(keyValuePair.Key))
            //    {
            //        _retval.Add(keyValuePair.Key, keyValuePair.Value);
            //    }
            //}

            //return _retval;
        }

        #endregion

        #region Get Key/Section Names

        /// <summary>
        /// Gets the names of all keys under a specific section in the ini file.
        /// </summary>
        /// <param name="sectionName">
        /// The name of the section to read key names from.
        /// </param>
        /// <returns>An array of key names.</returns>
        /// <remarks>
        /// The total length of all key names in the section must be 
        /// less than 32KB in length.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference  (Nothing in VB)
        /// </exception>
        public string[] GetKeyNames(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            string[] _retval;
            
            //Allocate a buffer for the returned section names.
            IntPtr _ptr = Marshal.AllocCoTaskMem(IniFile.MAX_SECTION_SIZE);
            try
            {
                //Get the section names into the buffer.
                int _len = NativeMethods.GetPrivateProfileString(
                    sectionName,
                    null,
                    null,
                    _ptr,
                    MAX_SECTION_SIZE,
                    Path);

                _retval = ConvertNullSeperatedStringToStringArray(_ptr, _len);
            }
            finally
            {
                //Free the buffer
                Marshal.FreeCoTaskMem(_ptr);
            }

            return _retval;
        }

        /// <summary>
        /// Gets the names of all sections in the ini file.
        /// </summary>
        /// <returns>An array of section names.</returns>
        /// <remarks>
        /// The total length of all section names in the section must be 
        /// less than 32KB in length.
        /// </remarks>
        public string[] GetSectionNames()
        {
            string[] _retval;

            //Allocate a buffer for the returned section names.
            IntPtr _ptr = Marshal.AllocCoTaskMem(IniFile.MAX_SECTION_SIZE);
            try
            {
                //Get the section names into the buffer.
                int _len = NativeMethods.GetPrivateProfileSectionNames(_ptr, MAX_SECTION_SIZE, Path);
                _retval = ConvertNullSeperatedStringToStringArray(_ptr, _len);
            }
            finally
            {
                //Free the buffer
                Marshal.FreeCoTaskMem(_ptr);
            }
            
            return _retval;
        }

        /// <summary>
        /// Converts the null seperated pointer to a string into a string array.
        /// </summary>
        /// <param name="ptr">A pointer to string data.</param>
        /// <param name="valLength">
        /// Length of the data pointed to by <paramref name="ptr"/>.
        /// </param>
        /// <returns>
        /// An array of strings; one for each null found in the array of characters pointed
        /// at by <paramref name="ptr"/>.
        /// </returns>
        private static string[] ConvertNullSeperatedStringToStringArray(IntPtr ptr, int valLength)
        {
            string[] _retval = new string[0];

            if (valLength > 0)
            {
                //Convert the buffer into a string.  Decrease the length 
                //by 1 so that we remove the second null off the end.
                string _buff = Marshal.PtrToStringAuto(ptr, valLength - 1);

                //Parse the buffer into an array of strings by searching for nulls.
                _retval = _buff.Split('\0');
            }

            return _retval;
        }

        #endregion

        #region Write Methods

        /// <summary>
        /// Writes a <see cref="T:System.String"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The string value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        private void WriteValueInternal(string sectionName, string keyName, string value)
        {
            if (!NativeMethods.WritePrivateProfileString(sectionName, keyName, value, Path))
                throw new System.ComponentModel.Win32Exception();
        }

        /// <summary>
        /// Writes a <see cref="T:System.String"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The string value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> or 
        /// <paramref name="value"/>  are a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, string value)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            if (value == null)
                throw new ArgumentNullException("value");

            WriteValueInternal(sectionName, keyName, value);
        }

        /// <summary>
        /// Writes an <see cref="T:System.Int16"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        public void WriteValue(string sectionName, string keyName, short value)
        {
            WriteValue(sectionName, keyName, (int)value);
        }

        /// <summary>
        /// Writes an <see cref="T:System.Int32"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, int value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        /// <summary>
        /// Writes an <see cref="T:System.Single"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, float value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        /// <summary>
        /// Writes an <see cref="T:System.Double"/> value to the ini file.
        /// </summary>
        /// <param name="sectionName">The name of the section to write to .</param>
        /// <param name="keyName">The name of the key to write to.</param>
        /// <param name="value">The value to write</param>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The write failed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void WriteValue(string sectionName, string keyName, double value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        #endregion

        #region Delete Methods

        /// <summary>
        /// Deletes the specified key from the specified section.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to remove the key from.
        /// </param>
        /// <param name="keyName">
        /// Name of the key to remove.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> or <paramref name="keyName"/> are 
        /// a null reference  (Nothing in VB)
        /// </exception>
        public void DeleteKey(string sectionName, string keyName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            WriteValueInternal(sectionName, keyName, null);
        }

        /// <summary>
        /// Deletes a section from the ini file.
        /// </summary>
        /// <param name="sectionName">
        /// Name of the section to delete.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sectionName"/> is a null reference (Nothing in VB)
        /// </exception>
        public void DeleteSection(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            WriteValueInternal(sectionName, null, null);
        }

        #endregion
    }



велосипед с единственной целью - сортировать секции в файле.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678537
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7велосипед с единственной целью - сортировать секции в файле.
Это шикарно :-) Я даже не буду спрашивать - зачем :-) Я лишь спрошу одно - где вы заявляли, что порядок следования важен?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678555
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arm79jenya7велосипед с единственной целью - сортировать секции в файле.
Это шикарно :-) Я даже не буду спрашивать - зачем :-) Я лишь спрошу одно - где вы заявляли, что порядок следования важен?

когда есть 200-300 секций в файле и в каждой секции 10-20 ключей довольно затруднительно найти нужную секцию а когда они сортированы это гораздо проще.
а я про порядок следования и не говорил. изначально вопрос был о другом. :-)
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678556
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7200-300 секций в файле
Вы уверены, что выбрали правильный инструмент для хранения настроек?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678561
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arm79jenya7200-300 секций в файле
Вы уверены, что выбрали правильный инструмент для хранения настроек?
неуверен но пока все иднт гладко. а что вы предлагаете? XML? DataBase?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678567
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7,
ini files являются инородными в net http://stackoverflow.com/questions/2475811/app-config-vs-ini-files
ps лично я не имею против них ничего, но в промышленной разработке наверное лучше придерживаться единого стандарта?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678580
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7неуверен но пока все иднт гладко. а что вы предлагаете? XML? DataBase?

Скажем там.

Во-первых, как уже сказал человек из таганрогских степей, сами по себе ini-файлы не родная для .Net. Поэтому, без особых показаний, я бы использовал именно Xml. Смотрите общепринятые практики хранения конфигураций и настроек.

Во-вторых, 300 секций для ini - это хоть и некритично, но очень смущает. Откуда они вообще у вас в таком количестве?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678601
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arm79jenya7неуверен но пока все иднт гладко. а что вы предлагаете? XML? DataBase?

Скажем там.

Во-первых, как уже сказал человек из таганрогских степей, сами по себе ini-файлы не родная для .Net. Поэтому, без особых показаний, я бы использовал именно Xml. Смотрите общепринятые практики хранения конфигураций и настроек.

Во-вторых, 300 секций для ini - это хоть и некритично, но очень смущает. Откуда они вообще у вас в таком количестве?

ну скажем есть линейка продукта - драйвер для серво двигателя.
линейка представлена несколькими амперажами - 1.5А, 3А, 4.5А, 6А, 10А, 13А, 20А, 30А. каждый драйвер имеет несколько модификаций - с таким протоколом, с другим протоколом, и так далее. кроме того есть несколько клиентов.
итак - 8 амперажей * 10 модификаций * 5 клиентов = 400 номеров продукта.
под каждый номер открыается секция.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678642
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7драйвер для серво двигателя.
Вы драйверы пишете на C#? Смелое решение :-)

В общем и целом, в порядке убывания приоритета (все ИМХО)
1) Использовать стандартные возможности хранения настроек, принятые в .Net
2) Если все-таки Ini, то не запариваться с сортировкой секций. Это бессмысленно
3) Можете сделать инсталлятор, и в нем сгенерировать тот вариант Ini, который вам нужен
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678658
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7,

авторну скажем есть линейка продукта - драйвер для серво двигателя.
линейка представлена несколькими амперажами - 1.5А, 3А, 4.5А, 6А, 10А, 13А, 20А, 30А. каждый драйвер имеет несколько модификаций - с таким протоколом, с другим протоколом, и так далее. кроме того есть несколько клиентов.
итак - 8 амперажей * 10 модификаций * 5 клиентов = 400 номеров продукта.
под каждый номер открыается секция.

гыгыгы
8 амперажей - enum
10 модификаций - туда же..
итого в настройках одна запись массив номеров продукта..
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678792
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
да нет. драйвер пишется для DSP в embedded. а секции нужны для других целей. например там храняться файлы скриптов и многое другое касательно данной модели.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678881
Фотография pation
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7да нет. драйвер пишется для DSP в embedded. а секции нужны для других целей. например там храняться файлы скриптов и многое другое касательно данной модели.

коль скоро такое количество данных, не подумать ли в сторону Sqlite?
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38678892
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всех спасёт православный XmlSerializer.
...
Рейтинг: 0 / 0
Записать в текстовый файл построчно.
    #38680053
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
XML сериализацией ты сможешь загрузить свой файлег и сохранить 3мя строчками кода, при этом списки можешь упорядочивать как тебе угодно, включая секции.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Записать в текстовый файл построчно.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]