参考链接:
http://baike.baidu.com/link?url=2pZNZUhdXpLZqvjzWdoCJjnOq-ncGt0jQveoZjvLq0HtxLKjLsrEvYA7t_TUaRxvh3aYWt0NFs4PQD2IBevgUa#7
http://www.cnblogs.com/laozuan/archive/2012/04/24/2467888.html
http://www.xuanyusong.com/archives/1919
字符编码的重要性:
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。
因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
基础知识:
1字节=8位,可以表示256个字符,从8个0到8个1
c#数据类型占用的字节数:
bool -> System.Boolean (布尔型,其值为 true 或者 false)
byte -> System.Byte (字节型,占 1 字节,表示 8 位正整数,范围 0 ~ 255)
sbyte -> System.SByte (带符号字节型,占 1 字节,表示 8 位整数,范围 -128 ~ 127)
char -> System.Char (字符型,占2字节,表示 1 个 Unicode 字符)
short -> System.Int16 (短整型,占 2 字节,表示 16 位整数,范围 -32,768 ~ 32,767)
ushort -> System.UInt16 (无符号短整型,占 2 字节,表示 16 位正整数,范围 0 ~ 65,535)
uint -> System.UInt32 (无符号整型,占 4 字节,表示 32 位正整数,范围 0 ~ 4,294,967,295)
int -> System.Int32 (整型,占 4 字节,表示 32 位整数,范围 -2,147,483,648 到 2,147,483,647)
float -> System.Single (单精度浮点型,占 4 个字节)
ulong -> System.UInt64 (无符号长整型,占 8 字节,表示 64 位正整数,范围 0 ~ 大约 10 的 20 次方)
long -> System.Int64 (长整型,占 8 字节,表示 64 位整数,范围大约 -(10 的 19) 次方 到 10 的 19 次方)
double -> System.Double (双精度浮点型,占8 个字节)
0.
a.二进制,逢二进一,主要用在加减法的运算
例:1011 + 11 = 1110
b.0x开头,表示十六进制(是数字0,不是字母o)
例:0x100F
1.& 与
类似于"and",两个二进制数,均为1时结果为1,否则为0
例:0000 1001 & 0000 0101 = 0000 0001
2.| 或
类似于"or",两个二进制数,只要有1结果为1,否则为0
例:0000 1001 | 0000 0101 = 0000 1101
与、或运算通常用于将某些位清零,或者保留某些位
例:a & 0000 1111 表示将高四位清零,保留低四位
3.<< 左移
左移运算是将一个二进制位的操作数按指定移动的位数向左移位,移出位被丢弃,右边的空位一律补0
4.>> 右移
右移运算是将一个二进制位的操作数按指定移动的位数向右移动,移出位被丢弃,左边的空位一律补0,
或者补符号位,这由不同的机器而定
常见字符编码:
1. ASCII码
ASCII码一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0。
缺点:英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。
2.Unicode(相当于UTF-16)
Unicode是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,可以解决乱码问题。一个Unicode字符由两个字节组成。
缺点:Unicode固然统一了编码方式,但是它的效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节存储一个符号,那么每个英文字母前都必然有三个字节是0,这对存储和传输来说都很耗资源。
3.UTF-8
为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长短。比如英文字母可以只用1个字节就够了。
UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
4.GBK
GBK采用双字节表示,解决汉字编码的问题。
c#中二进制文件的读写:
BinaryWriter类:https://msdn.microsoft.com/zh-cn/library/system.io.binarywriter.aspx
BinaryReader类:https://msdn.microsoft.com/zh-cn/library/system.io.binaryreader.aspx
Array.Copy:从指定的源索引开始,复制 Array 中的一系列元素,将它们粘贴到另一Array 中(从指定的目标索引开始)。
public static void Copy(
Array sourceArray,
int sourceIndex,
Array destinationArray,
int destinationIndex,
int length
)
using UnityEngine;
using System.Collections;
using System.IO;
using System.Text;
using UnityEditor;
public class TestByte : MonoBehaviour {
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1)) WriteByte();
if (Input.GetKeyDown(KeyCode.Alpha2)) ReadByte();
}
void WriteByte()
{
string path = Application.dataPath + @"/binary.txt";
if (File.Exists(path))
File.Delete(path);
FileStream fs = new FileStream(path,FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write("宏哥");
bw.Write((short)1995);
bw.Write((int)2015);
bw.Write((float)530);
bw.Write(true);
bw.Close();
fs.Close();
AssetDatabase.Refresh();
}
void ReadByte()
{
string path = Application.dataPath + @"/binary.txt";
FileStream fs = new FileStream(path, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
print(br.ReadString());
print(br.ReadInt16());
print(br.ReadInt32());
print(br.ReadSingle());
print(br.ReadBoolean());
br.Close();
fs.Close();
}
}
二进制文件:
输出:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
TestMemoryStream();
TestBinaryReaderWriter();
Console.ReadLine();
}
static void TestMemoryStream()
{
//如果使用文件流,则信息会被写进文件中
//而使用内存流,则信息会被写进内存中,不会产生额外的文件
MemoryStream ms = new MemoryStream();
//将待写入的数据从字符串转换为字节数组
byte[] testBytes = Encoding.UTF8.GetBytes("测试数据");
PrintInfo(ms);
ms.Write(testBytes, 0, testBytes.Length);
PrintInfo(ms);
//SeekOrigin的三种取值:
//1.Begin 指定流的开头 2.Current 指定流内的当前位置 3.End 指定流的结尾
//将position重定位为开头
ms.Seek(0, SeekOrigin.Begin);
byte[] bytes = new byte[testBytes.Length];
ms.Read(bytes, 0, bytes.Length);
Console.WriteLine("bytes:{0}", Encoding.UTF8.GetString(bytes, 0, bytes.Length));
PrintInfo(ms);
byte[] buffer = ms.GetBuffer();
Console.WriteLine("buffer:{0}", Encoding.UTF8.GetString(buffer, 0, buffer.Length));
PrintInfo(ms);
}
static void PrintInfo(MemoryStream ms)
{
Console.WriteLine("Capacity:{0}", ms.Capacity);
Console.WriteLine("Length:{0}", ms.Length);
Console.WriteLine("Position:{0}", ms.Position);
Console.WriteLine();
}
static void TestBinaryReaderWriter()
{
MemoryStream ms = new MemoryStream();
BinaryReader br = new BinaryReader(ms);
BinaryWriter bw = new BinaryWriter(ms);
bw.Write("helloworld");
ms.Seek(0, SeekOrigin.Begin);
string s = br.ReadString();
Console.WriteLine("content:{0}",s);
//字符串的长度是可变的,因此无法确定字符串的字节数
//当使用BinaryWriter.Write写入字符串时,会用第一位来存储字符串的长度
ms.Seek(0, SeekOrigin.Begin);
byte[] bytes = ms.ToArray();
for (int i = 0; i < bytes.Length;i++ )
{
Console.WriteLine("content:{0}", bytes[i]);
}
}
}
}