您的位置:首页 > 编程语言 > C#

[C#基础]字符编码与二进制

2017-10-21 17:26 190 查看
本文转自:http://blog.csdn.net/lyh916/article/details/46274841,请点击链接查看大神原文,尊重大神版权。

参考链接:

https://baike.baidu.com/item/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81#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,

或者补符号位,这由不同的机器而定

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

[b]常见字符编码:


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]);
}
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: