C# 文件操作

本文介绍了C#中文件操作的基本方法,包括使用File和FileInfo类进行文件的创建、读取和写入,以及目录的创建和文件数量的统计。同时,文章还探讨了文件流的使用,如FileStream、StreamWriter和StreamReader,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

迫于生计,不得不从C/C++转行学习C#。最近找了一份C#开发的公司工作,目前在疯狂学习C#的语法,由于有C/C++的基础,所以学习起来也不算很难,但是学习到了文件,就觉得学习的压力来了。

今天上班花了一天时间在研究C#文件相关的操作,算是学习到了一点皮毛,现在把今天所学习到的知识点记录下来。


文件的打开

我所接触到的目前有两种:FileFileInfo.

FIle

File.Open(文件路径, 文件打开类型);
File.Open(path, FileMode.Open);

它的返回值是文件流类型:Stream、StreamWriter、StreamReader.

代码示例:

FileStream fs = null;       // 文件流
StreamWriter fw = null;     // 文件流写入器
string path = "file.txt";

// 判断文件是否存在,存在返回true,不存在返回false
if (!File.Exists(path)) {
    // 创建文件,文件所在目录:
    // 工程文件夹下bin文件夹下debug文件夹中
    fs = File.Create(path);
    Console.WriteLine("没有{0}该文件,已创建该文件成功", path);
} else {
    // 打开文件,以具体的文件打开方式去打开指定文件
    fs = File.Open(path, FileMode.Open);
    Console.WriteLine("文件打开成功!");
}

其中
File.Exists(文件名) :判断文件是否存在,存在返回true,不存在返回false;

File.Create(文件名) :创建一个文件文件所在目录:工程文件夹下bin文件夹下debug文件夹中;

StreamWriter :是文件流写入器

FileInfo

FileInfo fi = new FileInfo(文件名);
FileInfo fi = new FileInfo(filePath);

代码示例:

// 实例化FileInfo对象    
FileInfo fi = new FileInfo(filePath);

if (!fi.Exists) {   // 判断文件是否存在
fi.Create();    // 创建文件
Console.WriteLine("文件已创建!");
} else {
    Console.WriteLine("文件已存在!");
}

和 File 的用法基本一致

文件的关闭

文件流的对象.Close();

读取器与写入器

使用流进行对文件的写入与读取

定义

									文件名        文件打开方式
FileStream fileStream = File.Open(strFIleName, FileMode.OpenOrCreate);

或者:

// 使用文件流对象去实例化文件流写入器
								fs 是 FileStream对象
FileStream fw = new StreamWriter(fs);

代码示例:

FileStream fs = null;       // 文件流
StreamWriter fw = null;     // 文件流写入器
StreamReader fr = null;     // 文件流读取器
string path = "file.txt";

// 判断文件是否存在,存在返回true,不存在返回false
    if (!File.Exists(path)) {
        // 创建文件,文件所在目录:
        // 工程文件夹下bin文件夹下debug文件夹中
        fs = File.Create(path);
        Console.WriteLine("没有{0}该文件,已创建该文件成功", path);
    } else {
        // 打开文件,以具体的文件打开方式去打开指定文件
         fs = File.Open(path, FileMode.Open);
         Console.WriteLine("文件打开成功!");
    }
            
    // 使用文件流对象去实例化文件流写入器
    fw = new StreamWriter(fs);
    fw.WriteLine("将字符串写入文件,并且换行");
    fw.Write("将字符串写入文件");

            
	// 文件流读取器,读取文件中的内容
    fr = new StreamReader(fs);
    string str;
    while (fr.Peek() != -1) {
        str = fr.ReadLine();
        Console.WriteLine("读取到的文件内容是:{0}", str);

    }

        
    // 刷新文件中的文本内容,并清空输入缓冲区的数据流
    fw.Flush();

    // 关闭文件流写入器
    fw.Close();
    fr.Close();

    // 关闭文件流
    fs.Close();
}

其中:
fr.Peek() != -1 : 读取文件,当读到文件尾部时结束
fr.ReadLine(); : 读取一行
fw.Flush(); : 刷新文件中的文本内容,并清空输入缓冲区的数据流

创建文件夹(目录)

// 获取当前目录路径
string dirPath = Directory.GetCurrentDirectory() + "/MyDir";
Console.WriteLine(dirPath);

// 判断目录是否存在,存在返回true,不存在返回false
if (!Directory.Exists(dirPath)) {
    // 创建目录
    Directory.CreateDirectory(dirPath);
    Console.WriteLine("文件夹创建成功!");
 } else {
    Console.WriteLine("文件夹已存在!");
    }

string filePath = dirPath + "/" + "a.txt";
Console.WriteLine(filePath);

/***********************************/
/* 下面是使用FileInfo创建文件 */
// 实例化FileInfo对象    
FileInfo fi = new FileInfo(filePath);

if (!fi.Exists) {   // 判断文件是否存在
    fi.Create();    // 创建文件
    Console.WriteLine("文件已创建!");
} else {
    Console.WriteLine("文件已存在!");
}

直接看代码吧,我也不知道该怎么写下来!!!

代码中重要部分都有详细注释

获取当前目录的文件个数

// 获取工程目录路径
string dirPath = Directory.GetCurrentDirectory();

// 获取工程目录下的所有文件路径
string[] str = Directory.GetFiles(dirPath);
Console.WriteLine(dirPath + "  文件个数:" + str.Length);
            
// 输出所有的工程路径下的文件路径
foreach (string s in str) {
    Console.WriteLine(s);
}

文件定位指针

Seek

// 文件指针定位到起始位置
     偏移量      从开始位置
fs.Seek(0, SeekOrigin.Begin);

代码示例:

string filePath = "text.txt";

using (FileStream fs = File.Open(filePath, FileMode.OpenOrCreate)) {
    string str = "不是吧,阿sir!  yes!";

    // 定义字节数组,并将字符串转换为byte类型赋值给它
    byte[] strByte = Encoding.UTF8.GetBytes(str);

    // 将转换为byte类型的字符串写入文件中
    fs.Write(strByte, 0, strByte.Length);

    // 定义一个字节数组
    byte[] readRead = new byte[strByte.Length];

    // 文件指针定位到起始位置
    fs.Seek(0, SeekOrigin.Begin);

    // 读取文件的一行
    fs.Read(readRead, 0, strByte.Length);

    // 输出字节数组中的字符串
    Console.WriteLine(Encoding.UTF8.GetString(readRead));
}

使用uing修饰可以自动关闭文件

但是用FileStream也可以写入和读取文件。

注意:

// 定义字节数组,并将字符串转换为byte类型赋值给它
byte[] strByte = Encoding.UTF8.GetBytes(str);

byte字节输出也需要转换为string类型开会有打印输出效果

Console.WriteLine(Encoding.UTF8.GetString(readRead));

其中:
fs.Seek(0, SeekOrigin.Begin);
SeekOrigin.Begin : 指向流的开头。
SeekOrigin.Current : 指向当前位置。
SeekOrigin.End : 指向流的结尾。

异步

这个不会,我把代码写下来,有兴趣的小伙伴自己可以去研究一下。

public void test7() {
            string str = "test.txt";
            FileInfo info = new FileInfo(str);
            FileStream fs = null;

            // 如果文件不存在
            if (!info.Exists) {
                info.Create();
                Console.WriteLine("文件创建成功!");
            } else {
                Console.WriteLine("文件已存在!");
            }

            fs = new FileStream(str, FileMode.Open, FileAccess.Write, FileShare.None, 4096, true);

            string sss = "BeiJing";

            byte[] vsByte = Encoding.UTF8.GetBytes(sss);

            Console.WriteLine("开始异步!");
            IAsyncResult asyncResult = fs.BeginWrite(vsByte, 0, vsByte.Length, new AsyncCallback(callBackFunc), fs);
        }

public static void callBackFunc(IAsyncResult asynResult) {
    Console.WriteLine("回调函数!");
    FileStream stream = asynResult.AsyncState as FileStream;

    if (stream != null) {
        stream.EndWrite(asynResult);
        stream.Close();
        Console.WriteLine("异步结束!");
    }
}

Mian函数测试和运行及图:

StreamFile streamFile = new StreamFile();
    streamFile.test7();
    for (int i = 0; i < 1000; i++) {
        Console.WriteLine(i);
    }

在这里插入图片描述

异步就是同步执行两种以上的操作!



好了,差不多就这样了,再深入我也不会了,自己慢慢体会吧!

下班!!!

<think>好的,用户想在ArcGIS或QGIS中对DEM进行重分类。首先,我需要回忆一下这两个软件中关于重分类的功能和步骤。记得在ArcGIS里,重分类通常是通过Spatial Analyst工具里的Reclassify工具完成的。而在QGIS中,可能使用的是Raster Calculator或者Reclassify by Table之类的插件或处理工具。 用户可能对DEM数据不太熟悉,所以需要先解释什么是重分类。重分类就是将栅格中的数值重新映射到新的类别或范围,比如将高程分成不同的等级,用于分析地形或制作地图。不过,用户已经提到了DEM,所以可能已经了解基本概念,但应用步骤是关键。 接下来,要分步骤说明在两个软件中的操作流程。对于ArcGIS,需要确保Spatial Analyst扩展模块已经启用,然后找到Reclassify工具,选择输入栅格,设置分类规则,比如手动划分间隔或使用分类方法(自然间断点、等间隔等),然后指定输出路径。需要提醒用户注意分类方法的适用场景,比如等间隔适合均匀分布的数据,而自然间断点则根据数据分布自动划分。 对于QGIS,可能步骤稍有不同。QGIS默认可能没有直接的Reclassify工具,但可以通过Raster Calculator使用条件语句来重新分类,或者安装Reclassify插件。比如使用GRASS GIS的r.reclass模块,或者SAGA GIS的重分类工具。需要详细说明每种方法的具体步骤,比如在Processing Toolbox里搜索相关工具,设置旧值到新值的映射表,或者使用表达式进行条件赋值。 另外,用户可能会遇到常见问题,比如分类后数据范围不正确,或者输出结果不显示。这时候需要检查输入数据的值域,确认分类规则是否正确覆盖了所有可能的值,或者检查是否忽略了某些特殊值(如Nodata)。此外,输出格式的选择也可能影响结果,建议使用GeoTIFF等常见格式以确保兼容性。 还要考虑用户的实际应用场景。例如,重分类可能用于洪水模拟,将高程分为淹没区和非淹没区;或者用于土地利用规划,划分不同的坡度等级。不同的应用可能需要不同的分类策略,因此提供一些实例会有帮助。 最后,生成相关问题时,需要围绕DEM处理的其他操作,比如坡度计算、山体阴影生成,或者与其他软件的比较,比如如何选择ArcGIS和QGIS进行这类操作。可能还要涉及数据预处理步骤,比如如何纠正DEM中的错误或填补缺失值。</think>### 如何在 ArcGIS 或 QGIS 中对 DEM 进行重分类? #### **ArcGIS 操作步骤** 1. **启用 Spatial Analyst 扩展** 打开 ArcMap 或 ArcGIS Pro,依次点击 `Customize > Extensions`,勾选 `Spatial Analyst`[^1]。 2. **打开重分类工具** 在 `Toolbox` 中导航至 `Spatial Analyst Tools > Reclass > Reclassify`。 3. **设置参数** - 输入栅格:选择 DEM 数据。 - 分类方法:支持手动划分区间或自动分类(如自然间断点、等间隔)。 - 输出栅格:指定保存路径。 ```python # 示例:通过代码调用工具 arcpy.Reclassify_3d("dem.tif", "VALUE", "0 500 1;500 1000 2;1000 1500 3", "output_reclass.tif") ``` 4. **验证结果** 检查输出栅格的属性表,确认高程值已按规则映射到新类别。 --- #### **QGIS 操作步骤** 1. **使用 Raster Calculator** - 打开 `Raster Calculator`(Processing Toolbox 中搜索)。 - 输入条件表达式,例如将高程分为三类: ``` (dem@1 <= 500) * 1 + (dem@1 > 500 AND dem@1 <= 1000) * 2 + (dem@1 > 1000) * 3 ``` - 指定输出格式为 GeoTIFF。 2. **通过插件重分类(如 Reclassify by Table)** - 安装 `Reclassify by Table` 插件。 - 定义旧值范围与新值的映射表,例如: | 旧值范围 | 新值 | |----------|------| | 0-500 | 1 | | 500-1000 | 2 | | >1000 | 3 | 3. **GRASS GIS 工具** 在 Processing Toolbox 中搜索 `r.reclass`,上传规则文件(如 `rules.txt`)定义分类规则。 --- #### **常见问题与注意事项** - **数据范围不匹配**:检查 DEM 的元数据,确认高程值范围是否覆盖分类区间。 - **Nodata 处理**:在 QGIS 中可通过 `Raster Calculator` 添加条件 `ELSE 0` 或保留原值。 - **分类方法选择**: - 等间隔:适用于均匀分布的高程数据。 - 自然间断点:适合突出地形突变区域[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值