C# 使用文件流来读写ini文件
背景
之前采用ini文件作为程序的配置文件,觉得这种结构简单明了,配置起来也挺方便。然后操作方式是通过WindowsAPI,然后再网上找到一个基于WindowsAPI封装的help类,用起来倒也顺手。用的多了,觉得还可以使用文件流来操作,后来就发现了EasyConfig。
EasyConfig是一个纯C#的开源ini文件操作库,但是在使用上有诸多不便,只是个人感觉,于是个人将其改造了一下,是自己喜欢用的风格。
资源下载
如果不清楚ini文件结构,请百度一下,这里贴一个示例文件。
[Video]
#是否全屏
Fullscreen = true
#宽度 Width = 1280 #电视高度
#高度
Height = 720 [Level1]
NumberOfEnemies=2000#数值
Lives = 10
Timer = 999
EnemyNames = "Steve", "Sam", "Bill"
EnemyGuns = 13, 28, 43, 499
CanShoot = true, yes, on, no, false, off
Ini文件示例
代码示例
首先来看看改写后,怎么去使用她来读写Ini文件。
static void Main(string[] args)
{
ConfigFile configFile = new ConfigFile("Test.ini"); //遍历Config文件
foreach (var group in configFile.SettingGroups)
{
Console.WriteLine("****************************");
Console.WriteLine(group.Key + ":");
Console.WriteLine(); foreach (var value in group.Value.Settings)
Console.WriteLine("{0} = {1} (Is Array? {2}),{3}", value.Key, value.Value.RawValue, value.Value.IsArray, value.Value.Desp); Console.WriteLine();
}
//读取值主要是在具体的配置项上进行读取,是首先定位到[Group],其次就是具体的项
//使用泛型读取值,并指定读取失败时的默认值
var fullScreen = configFile["Video"]["Fullscreen"].As<int>(-);//失败
var bFullScreen = configFile["Video"]["Fullscreen"].AsBool();//成功
var arrCanShoot = configFile["Level1"]["CanShoot"].AsArray<bool>();
//读取时 该项不存在,不存在的组或者项会自动添加
var noexists = configFile["Video"]["xxxxxxxxxxx"].AsString();
var noexists2 = configFile["Video111111111"]["xxxxxxxxxxx"].AsString(); //写入值有2种方法,可以直接向某组下写入一项,也可以定位到某组某项,写入值
//写入值 该项不存在,组或者项会自动创建
configFile["Video"].WriteSetting("NewName", "EasyConfig");
configFile["Video"].WriteSetting("NewName", "EasyConfig2.0");
configFile["Video22222222"].WriteSetting("c1", "");
//索引器不过是返回Setting
configFile["Video3333"]["UserName"].SetValue("admin");
configFile["Viedo4444"]["Sex"].SetValue("男", "女", "保密");
//写入值,该项不存在
configFile["Video222"].WriteSetting("NewName", "EasyConfig3.0"); Console.ReadKey(true); configFile.Save("TestConfig2.txt");
}
基本上自己想要的效果,则是基于 ConfigFile["GroupName"]["Key"] 这样的方式来进行读写。
另外附上一个基于WindowsAPI操作的封装类。
/// <summary>
/// Provides methods for reading and writing to an INI file.
/// </summary>
public class IniFileHelp
{
/// <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 MaxSectionSize = ; // 32 KB //The path of the file we are operating on.
private string m_path; #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 /// <summary>
/// Initializes a new instance of the <see cref="IniFileHelp"/> class.
/// </summary>
/// <param name="path">The ini file to read and write from.</param>
public IniFileHelp(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.
m_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
{
return m_path;
}
} #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(IniFileHelp.MaxSectionSize); NativeMethods.GetPrivateProfileString(sectionName,
keyName,
defaultValue,
retval,
IniFileHelp.MaxSectionSize,
m_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, m_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, ""); if (retval == null || retval.Length == )
{
return defaultValue;
} return 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)
{
List<KeyValuePair<string, string>> retval;
string[] keyValuePairs;
string key, value;
int equalSignPos; if (sectionName == null)
throw new ArgumentNullException("sectionName"); //Allocate a buffer for the returned section names.
IntPtr ptr = Marshal.AllocCoTaskMem(IniFileHelp.MaxSectionSize); try
{
//Get the section key/value pairs into the buffer.
int len = NativeMethods.GetPrivateProfileSection(sectionName,
ptr,
IniFileHelp.MaxSectionSize,
m_path); keyValuePairs = ConvertNullSeperatedStringToStringArray(ptr, len);
}
finally
{
//Free the buffer
Marshal.FreeCoTaskMem(ptr);
} //Parse keyValue pairs and add them to the list.
retval = new List<KeyValuePair<string, string>>(keyValuePairs.Length); for (int i = ; i < keyValuePairs.Length; ++i)
{
//Parse the "key=value" string into its constituent parts
//Cancel a string start with '#'
var item = keyValuePairs[i].Trim();
if (item.Length > && !item.StartsWith("#"))
{
equalSignPos = keyValuePairs[i].IndexOf('=');
key = keyValuePairs[i].Substring(, equalSignPos); value = keyValuePairs[i].Substring(equalSignPos + ,
keyValuePairs[i].Length - equalSignPos - ); retval.Add(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)
{
List<KeyValuePair<string, string>> keyValuePairs;
Dictionary<string, string> retval; keyValuePairs = GetSectionValuesAsList(sectionName); //Convert list into a dictionary.
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)
{
int len;
string[] retval; if (sectionName == null)
throw new ArgumentNullException("sectionName"); //Allocate a buffer for the returned section names.
IntPtr ptr = Marshal.AllocCoTaskMem(IniFileHelp.MaxSectionSize); try
{
//Get the section names into the buffer.
len = NativeMethods.GetPrivateProfileString(sectionName,
null,
null,
ptr,
IniFileHelp.MaxSectionSize,
m_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;
int len; //Allocate a buffer for the returned section names.
IntPtr ptr = Marshal.AllocCoTaskMem(IniFileHelp.MaxSectionSize); try
{
//Get the section names into the buffer.
len = NativeMethods.GetPrivateProfileSectionNames(ptr,
IniFileHelp.MaxSectionSize, m_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; if (valLength == )
{
//Return an empty array.
retval = new string[];
}
else
{
//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 - ); //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, m_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
}
IniFileHelp
C# 使用文件流来读写ini文件的更多相关文章
- 读写ini文件
C# 使用文件流来读写ini文件 背景 之前采用ini文件作为程序的配置文件,觉得这种结构简单明了,配置起来也挺方便.然后操作方式是通过WindowsAPI,然后再网上找到一个基于WindowsAPI ...
- windows服务 MVC之@Html.Raw()用法 文件流的读写 简单工厂和工厂模式对比
windows服务 public partial class Service1 : ServiceBase{ System.Threading.Timer recordTimer;public S ...
- 在 WinCe 平台读写 ini 文件
在上篇文章开发 windows mobile 上的今日插件时,我发现 wince 平台上不支持例如 GetPrivateProfileString 等相关 API 函数.在网络上我并没有找到令我满意的 ...
- c# 利用动态库DllImport("kernel32")读写ini文件(提供Dmo下载)
c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...
- VB读写INI文件的四个函数以及相关API详细说明
WritePrivateProfileString函数说明 来源:http://blog.csdn.net/wjb9921/article/details/2005000 在我们写的程序当中,总有一 ...
- C# 读写INI 文件
INI 格式: [Section1] KeyWord1 = Value1 KeyWord2 = Value2 ... [Section2] KeyWord3 = Value3 KeyWord4 = V ...
- WIN32读写INI文件方法
在程序中经常要用到设置或者其他少量数据的存盘,以便程序在下一次执行的时候可以使用,比如说保存本次程序执行时窗口的位置.大小.一些用户设置的 数据等等,在 Dos 下编程的时候,我们一般自己产生一个 ...
- Windows中读写ini文件
.ini 文件是Initialization File的缩写,即初始化文件,是windows的系统配置文件所采用的存储格式,来配置应用软件以实现不同用户的要求.配置文件有很多种如ini配置文件,XML ...
- C#中读写INI文件
C#中读写INI文件 c#的类没有直接提供对ini文件的操作支持,可以自己包装win api的WritePrivateProfileString和GetPrivateProfileString函数实现 ...
随机推荐
- 15,redis基础学习
redis Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件 yum安装redis 1.yum安装 #前提得配置好阿里云yum源,epel源 #查看 ...
- FIFO页面淘汰算法
1.优异虚拟存储系统,若进程在内存中占3页(开始时内存为空),若采用先进先出(FIFO)页面淘汰算法,当执行以下访问页号序列后1,3,4,2,1,3,5,1,2,5,4,2,会产生多少次缺页(9) 在 ...
- wireshark 安装
#yum install wireshark 安装完毕后 whereis wireshark 找不到可执行程序 /bin /sbin /usr/bin /usr/sbin下均没有. 实际上wiresh ...
- Android学习记录(4)—在java中学习多线程下载的基本原理和基本用法①
多线程下载在我们生活中非常常见,比如迅雷就是我们常用的多线程的下载工具,当然还有断点续传,断点续传我们在下一节来讲,android手机端下载文件时也可以用多线程下载,我们这里是在java中写一个测试, ...
- <<程序猿健康指南>> 笔记
序言: 长时间对着电脑工 作.一天下来基本不怎么走动的人,患高血压及 2 型糖尿病的风险远高于其他人群, 这两种疾病会对人体的健康产生长久的严重影响,还会增加心脏病及中风的几率. 前言: 阿米什人(A ...
- pythondifflib模块讲解示例
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Lockey23/article/details/77913855 difflib模块提供的类和方法用 ...
- Windows7中如何让python2和python3共存并使用pip
1.下载安装python2和python3 分别下载python2.7.exe.python3.6.exe并安装到C盘.E盘(如图) 2.配置环境变量 打开“系统变量”中的path文本框(如图 ...
- Linux认知之旅【03 进一步了解Linux命令】!
再仔细的研究一下命令,你会进一步提高提高对Linux的操作! 看完本文有空http://man.linuxde.net/转转!这是个好网站! 一.命令是什么? 计算机术语[command]:形容在对计 ...
- SPOJ - DQUERY(区间不同数+树状数组)
链接:SPOJ - DQUERY 题意:求给定区间不同数的个数(不更新). 题解:离线+树状数组. 对所求的所有区间(l, r)根据r从小到大排序.从1-n依次遍历序列数组,在树状数组中不断更新a[i ...
- PHP vscode+XDebug 远程断点调试服务器上的代码
对于简单的项目或仅仅想知道某一位置的某个变量是什么值,直接使用var_dump配置exit来打印和中断就可以了,方便又快捷, 而对于大型项目的调试,或想了解某个系统的整个运行过程,xdebug可能会是 ...