C#-文件的常见操作

读取

全部读取

1
2
byte[] fileBytes = File.ReadAllBytes("recorded_audio.wav");
Console.WriteLine($@"fileBytes.Length:{fileBytes.Length}");

流式按字节读取

常见的音频是16位为一个基本单元,所以我们可以16位一批一批的读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
string infilename = "recorded_audio.wav";
List<short> sArr = new List<short>();
try
{
using (FileStream fs = new FileStream(infilename, FileMode.Open)){
using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
{
while (fs.Position < fs.Length)
{
short temp = br.ReadInt16();
// 处理读取到的 short 数据
sArr.Add(temp);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"读取文件时出错: {ex.Message}");
}
Console.WriteLine(sArr.Count);

流式按行读取

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
public double[] ReadFile(string fname)
{
string strLine = "";
try
{
FileStream aFile = new FileStream(fname, FileMode.Open);
StreamReader sr = new StreamReader(aFile);
string s = sr.ReadLine();
while (s != null)
{
strLine += s;
s = sr.ReadLine();
}
sr.Close();
}
catch (IOException)
{
return null;
}
string[] data = strLine.Split(',');
int len = data.Length;
double[] p = new double[len];
for (int i = 0; i < len - 1; i++)
{
double d = double.Parse(data[i]);
p[i] = d;
}
return p;
}

字节数组

子数组

1
2
3
4
5
6
7
8
9
10
11
12
WaveIn cap = new WaveIn();
cap.WaveFormat = new WaveFormat(16000, 1);
cap.DataAvailable += (s, args) =>
{
byte[] subBytes = new byte[args.BytesRecorded];
Array.Copy(
args.Buffer,
subBytes,
args.BytesRecorded
);
}
cap.StartRecording();

转换

1
2
3
4
5
6
7
8
9
10
11
12
// 定义两个 byte 类型的值
byte byte1 = 0x12;
byte byte2 = 0x34;

// 创建一个包含这两个 byte 的字节数组
byte[] bytes = new byte[2] { byte1, byte2 };

// 使用 BitConverter.ToInt16 方法将字节数组转换为 short 类型
short result = BitConverter.ToInt16(bytes, 0);

// 输出结果
Console.WriteLine($"转换后的 short 值: {result}");

文本写入

在 C# 中,有多种方式可以实现文本写入操作,下面将详细介绍几种常见的方法。

使用 File.WriteAllText 方法

这种方法适合一次性将整个文本内容写入到文件中,它会覆盖文件中已有的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.IO;

class Program
{
static void Main()
{
string filePath = "test.txt";
string text = "这是要写入文件的文本内容。";

try
{
// 将文本写入文件
File.WriteAllText(filePath, text);
System.Console.WriteLine("文本写入成功!");
}
catch (IOException e)
{
System.Console.WriteLine($"写入文件时发生错误: {e.Message}");
}
}
}

代码解释:

  • File.WriteAllTextSystem.IO 命名空间下 File 类的静态方法。
  • 它接受两个参数,第一个参数是文件的路径,第二个参数是要写入文件的文本内容。
  • 若文件不存在,该方法会创建新文件;若文件已存在,则会覆盖原有内容。

使用 File.AppendAllText 方法

如果只是想简单地追加文本到文件末尾,可使用 File.AppendAllText 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.IO;

class Program
{
static void Main()
{
string filePath = "test.txt";
string text = "这是追加到文件的文本内容。";

try
{
// 追加文本到文件
File.AppendAllText(filePath, text);
System.Console.WriteLine("文本追加成功!");
}
catch (IOException e)
{
System.Console.WriteLine($"写入文件时发生错误: {e.Message}");
}
}
}

代码解释:

  • File.AppendAllTextFile 类的静态方法,用于将指定的文本追加到文件末尾。
  • 若文件不存在,会创建新文件。

使用 StreamWriter

StreamWriter 类提供了更灵活的文本写入方式,可以逐行写入或追加内容到文件。

覆盖写入

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
using System.IO;

class Program
{
static void Main()
{
string filePath = "test.txt";
string text = "这是要写入文件的文本内容。";

try
{
// 创建 StreamWriter 实例,使用 using 语句确保资源正确释放
using (StreamWriter writer = new StreamWriter(filePath))
{
// 写入文本
writer.Write(text);
}
System.Console.WriteLine("文本写入成功!");
}
catch (IOException e)
{
System.Console.WriteLine($"写入文件时发生错误: {e.Message}");
}
}
}

追加写入

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
using System.IO;

class Program
{
static void Main()
{
string filePath = "test.txt";
string text = "这是追加到文件的文本内容。";

try
{
// 创建 StreamWriter 实例,第二个参数为 true 表示追加写入
using (StreamWriter writer = new StreamWriter(filePath, true))
{
// 写入文本
writer.WriteLine(text);
}
System.Console.WriteLine("文本追加成功!");
}
catch (IOException e)
{
System.Console.WriteLine($"写入文件时发生错误: {e.Message}");
}
}
}

代码解释:

  • StreamWriter 类用于将字符写入流,可指定文件路径创建实例。
  • 使用 using 语句可以确保在代码块结束时,StreamWriter 实例的资源被正确释放。
  • 构造函数的第二个参数 true 表示以追加模式打开文件,不指定或为 false 则是覆盖模式。
  • Write 方法用于写入文本,WriteLine 方法会在写入文本后添加换行符。

注意事项

  • 在进行文件操作时,可能会抛出 IOException 异常,因此最好进行异常处理。
  • 要确保程序有足够的权限在指定路径下创建或修改文件。

概念

byte/short

byte 是 1 个字节(即 8 位)。

short 是 2 个字节(即 16 位)。

C# 中的 short 实际上就是对 System.Int16 的别名映射。

int 是 4 个字节(即 32 位)。

long 是 8 个字节(即 64 位)。