import PrintHelper
import os
PrintHelper.PrintSubtitle('Binary Files,二进制文件')
print('计算系统的文件一般分为两类,二进制文件和纯文本文件')
print('图片,影音,word文档,可执行文件等等都算是二进制文件')
print('使用Python处理非二进制文件并不普遍,多是特殊目的的程序')
print('本章描述如何处理二进制文件')
PrintHelper.PrintSubtitle('Opening And Closing Binary Files,打开和关闭二进制文件')
print('对于二进制文件,你需要告诉文件句柄,你希望使用\"rb\"(read binary)模式读取文件')
print('写操作二进制文件时,则采用\"wb\"模式,读写模式为\"w+b\"模式,这两种模式都会清空原文件.')
print('关闭二进制文件和纯文本文件的操作没有区别')
print('你可以使用读写二进制文件的方式读写纯文本文件,这意味着少了字符编码转换的处理.')
PrintHelper.PrintSubtitle('Prepares')
PrintHelper.PrintCode('os.chdir(\"..\\..\\FilesForTest\")')
PrintHelper.PrintCode('print(os.getcwd())')
PrintHelper.PrintCode('filePath="a.txt"')
PrintHelper.PrintCode('print(filePath)')
os.chdir("..\..\FilesForTest")
print(os.getcwd())
filePath="a.txt"
print(filePath)
PrintHelper.PrintSubtitle('Reading A Binary File,读取二进制文件')
print('二进制文件没有行的概念')
print('二进制文件只有read()方法')
print('没有参数时,读完整个文件')
print('可以使用一个整数参数,代表着从开头开始读多少字节的数据')
print('从开始指针开始读相应的字符或者直到文件结尾.')
PrintHelper.PrintCode('with open(filePath,\"rb\") as fp:')
PrintHelper.PrintCode('    text=fp.read()')
PrintHelper.PrintCode('    print(text)')
PrintHelper.PrintCode('    for letter in text:')
PrintHelper.PrintCode('        print(letter,end=\" \")')
PrintHelper.PrintCode('print()')
with open(filePath,"rb") as fp:
    text=fp.read()
    print(text)
    for letter in text:
        print(letter,end=" ")
print()
PrintHelper.PrintCode('with open(filePath,\"rb\") as fp:')
PrintHelper.PrintCode('    print(fp.read(100))')
with open(filePath,"rb") as fp:
    print(fp.read(100))
PrintHelper.PrintCode('with open(filePath,\"rb\") as fp:')
PrintHelper.PrintCode('    print(fp.read(5))')
with open(filePath,"rb") as fp:
    print(fp.read(5))
PrintHelper.PrintSubtitle('Byte Strings,二进制字符串')
print('二进制字符串和字符串的区别')
print('比如\"hello world\"是字符串,b\"hello world\"则是二进制字符串')
print('你从二进制文件中读取出来的即是二进制字符串')
print('二进制字符串包含字符串所不能支持的字符')
print('二进制字符串和字符串一样可以通过指数来访问')
print('它直接输出的是数值,这和访问字符串时使用ord(@value)得到的值是一致的')
print('ord(@char)可以获得字符在默认编码下的数值')
print('字符是八位的二进制数,即在十进制下是一个数值')
print('在ASCII码下,\"A\"以65表示,空格则是32')
print('对于二进制字符串b\"h\\x20w\"和字符串\"h w\"是相同的')
print('二进制字符串和字符串的区别是,它读取字符串的字符数值')
print('而字符串则读取了这个数值在某个编码下的内容')
PrintHelper.PrintHint('b"@string"','ord(@char)')
PrintHelper.PrintCode('hwString = \"Hello, world!\"')
PrintHelper.PrintCode('hwBinaryString = b\"Hello, world!\"')
PrintHelper.PrintCode('for c in hwString:')
PrintHelper.PrintCode('    print( c, end=\" \" )')
PrintHelper.PrintCode('print()')
PrintHelper.PrintCode('for c in hwString:')
PrintHelper.PrintCode('    print( ord( c ), end=\" \" )')
PrintHelper.PrintCode('print()')
PrintHelper.PrintCode('for c in hwBinaryString:')
PrintHelper.PrintCode('    print( c, end=\" \" )')
PrintHelper.PrintCode('print()')
hwString = "Hello, world!"
hwBinaryString = b"Hello, world!"
for c in hwString:
    print( c, end=" " )
print()
for c in hwString:
    print( ord( c ), end=" " )
print()
for c in hwBinaryString:
    print( c, end=" " )
print()
PrintHelper.PrintHint('bytes(@byte[])','str(@BinaryString)')
print('以下编码展示了一个示例')
print('首先声明一个字符集合,BinaryString存储的即是byte[],可以直接输出为BinaryString,可以使用编码解码输出为字符串')
PrintHelper.PrintHint('@bytes.decode(@EncodingType[,@mode])','@mode可以为以下类型','无参数时默认进行编码,异常则抛出'
                      ,'ignore:忽略异常编码,仅显示有效的编码','replace:替换异常编码')
PrintHelper.PrintCode('binaryBytes=bytes([104,101,108,108,111,32,119,111,114,108,100])')
binaryBytes=bytes([104,101,108,108,111,32,119,111,114,108,100])
PrintHelper.PrintCode('print(binaryBytes)')
print(binaryBytes)
PrintHelper.PrintCode('print(binaryBytes.decode(\"utf-8\"))')
print(binaryBytes.decode("utf-8"))
PrintHelper.PrintSubtitle('Writing A Binary File,写二进制文件')
PrintHelper.PrintCode('with open(filePath,\"wb\") as fp:')
PrintHelper.PrintCode('    fp.write(b\"And now for something completely different...\\x0A\\x00\\ \\x00\\x00\\x00\\xD4\\xE8\\xE5\\xA0\\xD3\\xF0\\xE1\\xEE\\xE9\\xF3\\xE8\\xA0\\xC9\\ \\xEE\\xF1\\xF5\\xE9\\xF3\\xE9\\xF4\\xE9\\xEF\\xEE\\x00\\x00\\x00\")')
PrintHelper.PrintCode('with open(filePath,\"rb\") as fp:')
PrintHelper.PrintCode('    buffer = fp.readline()')
PrintHelper.PrintCode('    if buffer == \"\":')
PrintHelper.PrintCode('        break')
PrintHelper.PrintCode('    print( buffer ) ')
with open(filePath,"wb") as fp:
    fp.write(b"And now for something completely different...\x0A\x00\ \x00\x00\x00\xD4\xE8\xE5\xA0\xD3\xF0\xE1\xEE\xE9\xF3\xE8\xA0\xC9\ \xEE\xF1\xF5\xE9\xF3\xE9\xF4\xE9\xEF\xEE\x00\x00\x00")
with open(filePath) as fp:
    while True:
        buffer = fp.readline()
        if buffer == "":
            break
        print( buffer ) 
PrintHelper.PrintSubtitle('Positioning The File Pointer,定位文件指针')
print('定位文件指针可以在open()后对file handler使用seek()方法操控')
print('可以从开头查找0,从当前位置查找1,从结尾开始查找2,默认为0')
print('参数值可以为正数或者是负数')
PrintHelper.PrintHint('seek(@position[,@relativeMode])','@relativeMode如下','0:相对于起始位置','1:相对于当前位置','2:相对于结束位置'
                      ,"seek(@position)==seek(@position,0)")
PrintHelper.PrintCode('with open(filePath,\"rb\") as fp:')
PrintHelper.PrintCode('    fp.seek(5,0)')
PrintHelper.PrintCode('    print(fp.read(10))')
PrintHelper.PrintCode('    fp.seek(5,1)')
PrintHelper.PrintCode('    print(fp.read(10))')
PrintHelper.PrintCode('    fp.seek(-5,2)')
PrintHelper.PrintCode('    print(fp.read(10))')
PrintHelper.PrintCode('    fp.seek(-10,2)')
PrintHelper.PrintCode('    bstring=fp.read(10)')
PrintHelper.PrintCode('    for letter in bstring:')
PrintHelper.PrintCode('        print(letter,end=\" \")')
PrintHelper.PrintCode('    print()')
PrintHelper.PrintCode('    for letter in bstring:')
PrintHelper.PrintCode('        print(chr(letter),end=\" \")')
PrintHelper.PrintCode('    print()')
PrintHelper.PrintCode('    print(type(bstring))')
PrintHelper.PrintCode('    print(bstring.decode(\"gbk\",\"ignore\"))')
with open(filePath,"rb") as fp:
    fp.seek(5,0)
    print(fp.read(10))
    fp.seek(5,1)
    print(fp.read(10))
    fp.seek(-5,2)
    print(fp.read(10))
    fp.seek(-10,2)
    bstring=fp.read(10)
    for letter in bstring:
        print(letter,end=" ")
    print()
    for letter in bstring:
        print(chr(letter),end=" ")
    print()
    print(type(bstring))
    print(bstring.decode("gbk","ignore"))
    print(bstring.decode("gbk","replace"))

