精华内容
参与话题
问答
  • 大数据_05 【hadoop HDFS文件读写流程】01 文件写入过程02 文件读取过程03 数据校验04 DataNode节点丢失周期05 DataNode的目录结构 01 文件写入过程 详细步骤解析: 1、 client发起文件上传请求,通过RPC与NameNode...

    01 文件写入过程

    在这里插入图片描述

    详细步骤解析:
    1 client发起文件上传请求,通过RPC与NameNode建立通讯,NameNode检查目标文件是否已存在,父目录是否存在,返回是否可以上传;
    2 client请求第一个block该传输到哪些DataNode服务器上;
    3 NameNode根据配置文件中指定的备份数量及机架感知原理进行文件分配,返回可用的DataNode的地址如:A,B,C;
    
    4 client请求3台DataNode中的一台A上传数据(本质上是一个RPC调用,建立pipeline),A收到请求会继续调用B,然后B调用C,将整个pipeline建立完成,后逐级返回client;
    5 client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(默认64K),A收到一个packet就会传给B,B传给C;A每传一个packet会放入一个应答队列等待应答。
    6 数据被分割成一个个packet数据包在pipeline上依次传输,在pipeline反方向上,逐个发送ack(命令正确应答),最终由pipeline中第一个DataNode节点A将pipelineack发送给client;
    7、关闭写入流。
    8 当一个block传输完成之后,client再次请求NameNode上传第二个block到服务器。
    

    02 文件读取过程

    在这里插入图片描述

    1		客户端通过调用FileSystem对象的open()来读取希望打开的文件。
    2 	Client向NameNode发起RPC请求,来确定请求文件block所在的位置; 
    3 	NameNode会视情况返回文件的部分或者全部block列表,对于每个block,NameNode 都会返回含有该 block 副本的 DataNode 地址;  这些返回的 DN 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离 Client 近的排靠前;心跳机制中超时汇报的 DN 状态为 STALE,这样的排靠后; 
    4 	Client 选取排序靠前的 DataNode 来读取 block,如果客户端本身就是DataNode,那么将从本地直接获取数据(短路读取特性) 
    5 	底层上本质是建立 Socket Stream(FSDataInputStream),重复的调用父类 DataInputStream  read 方法,直到这个块上的数据读取完毕; 
    6		并行读取,若失败重新读取
    7 	当读完列表的 block 后,若文件读取还没有结束,客户端会继续向NameNode 获取下一批的 block 列表; 
    8		返回后续block列表
    9  	最终关闭读流,并将读取来所有的 block 会合并成一个完整的最终文件。
    

    03 数据校验

    在这里插入图片描述

    1	数据第一次写入成功后,会进行数据校验,获得校验和。
    2	数据读取前,对数据进行校验,获得校验和,计算得到的校验和与第一次上传后的校验和进行对比。
    3	两个校验和相同表示数据相同,可以提读取数据
    4	两个校验和不相同表示数据不相同,节点去其他节点读取
    
    5	数据节点周期进行校验和计算,防止数据丢失。
    

    04 DataNode节点丢失周期

    DataNode节点长时间没有给NameNode汇报心跳,NameNode认为其丢失。
    长时间(10分钟+30秒): 2 * 超时时间 + 10 * 心跳周期

    05 DataNode的目录结构

    和namenode不同的是,datanode的存储目录是初始阶段自动创建的,不需要额外格式化。在/export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas/current这个目录下查看版本号

    [root@node01 current]# cat VERSION 
    #Thu Mar 14 07:58:46 CST 2019
    storageID=DS-47bcc6d5-c9b7-4c88-9cc8-6154b8a2bf39
    clusterID=CID-dac2e9fa-65d2-4963-a7b5-bb4d0280d3f4
    cTime=0
    datanodeUuid=c44514a0-9ed6-4642-b3a8-5af79f03d7a4
    storageType=DATA_NODE
    layoutVersion=-56
    
    具体解释
    (1)storageID:		存储id号
    (2)clusterID		集群id,全局唯一
    (3)cTime			属性标记了datanode存储系统的创建时间,对于刚刚格式化的存储系统,这个属性为0;但是在文件系统升级之后,该值会更新到新的时间戳。
    (4)datanodeUuid:	datanode的唯一识别码
    (5)storageType:	存储类型
    (6)layoutVersion	是一个负整数。通常只有HDFS增加新特性时才会更新这个版本号。
    

    目录结构

    在这里插入图片描述

    展开全文
  • HDFS文件读写流程

    万次阅读 2019-11-12 22:23:00
  • Java文件读写

    万次阅读 2019-06-07 21:17:16
    1.%g用于输出科学计数法 2.用printf输出换行除了’\n’,还可以用’%n’ 3.File类的几个构造方法: 1)File(String directoryPath) 2)File(String directoryPath,String filename) 3)File(File dirObj,String ...

    1.%g用于输出科学计数法

    2.用printf输出换行除了’\n’,还可以用’%n’

    3.File类的几个构造方法:
    1)File(String directoryPath)
    2)File(String directoryPath,String filename)
    3)File(File dirObj,String filename)
    4)File(URI uri)
    注意,这里的对象指的可能是一个我们通常所说的文件,也可能是一个目录(路径);可以是个具体存在的文件,也可以是个尚未存在的文件。

    4.所谓的数据流是指一组有顺序的、有起点和终点的字节集合

    5.Java程序不能直接操纵I/O设备,而是在程序和设备之间加入了一个中间介质,这就是流。流是数据传输的抽象表达,与具体设备无关,程序一旦建立了流,就可以不用理会起点或终点是何种设备

    6.输入流将数据从文件、标准输入或者其它外部设备输入加载到内存。

    7.输入输出数据流:
    1)以字节流传输的输入数据流都是抽象类InputStream的子类;以字符流传输的输入数据流都是抽象类Reader的子类。
    2)以字节流传输的输出数据流都是抽象类OutputStream的子类;以字符流传输的输出数据流都是抽象类Writer的子类。

    8.类File一般不涉及文件内部的具体内容,而是从整体上对文件进行处理,如获取各种各样的文件消息或者删除文件。类File不仅可以对文件进行操作,而且还可以对路径进行操作。

    9.父目录:当前所在目录的上一层目录(文件夹)
    子目录:当前所在目录的下一层目录(文件夹)

    10.mark()通常与reset()方法配合使用,可重复读取输入流所指定的字节数据。例如:若fis是一个输入流,如果想读取相同的字 节数据到字节数组b1和b2中,可通过以下语句实 现,先标记输入流中当前位置,读取数据后重置 读取位置。

    fis.mark(5);
    byte[] b1=new byte[5], byte[] b2=new byte[5],
     fis.read(b1,0,5);
    fis.reset();
     Fis.read(b2,0,5);
    

    11.mark(int readlimit)方法表示标记当前位置,并保证在mark以后最多可以读取readlimit字节数据。reset()方法表示重置移动读取指针到上一次mark的地方。

    12.FileOutputStream用于向本地文件中写入数据,注意,是往本地文件中写入,不是向控制台输出。

    13.FileInputStream不支持缓冲和做标记

    14.InputStream和OutputStream都是抽象类,不能通过new OutputStream()的方法构造各自的实例。我们可以通过构造它们的子类的实例方式构造该类型的实例(类似于List和Arraylist的关系)。一个构造InputStreamReader实例的例子:

    new InputStreamReader(new FileInputStream("data.txt"));
    

    15.FilterInputStream:过滤器输入流是其它带过滤器的输入流的超类,它的方法和InputStream的方法完全一样,也就是说前者只是简单地重写了后者的所有方法。
    1)它的构造方法是FilterInputStream(InputStream in)。过滤器输入流以一个InputStream为自己的数据。
    2)成员变量:protected InputStream in。在构造方法里会对这个变量赋值,即this.in=in

    16.当创建BufferedInputStream或者BufferedOutputStream的实例时,均会在内存中开辟一个字节数组的存储单元(一般称为缓存),默认为512字节,用来存放数据流中的数据。

    17.通常情况下,缓冲区的大小应为内存页或者磁盘块等的整数倍,以避免页或块的浪费。

    18.write(int b):将b转成二进制后,把b的低8位写到输出流。把所有32位都写到输出流的函数是writeInt(int b)。

    19.使用对象流读取和写入对象时,要保证对象是串行化的。(串行化的概念:指对象通过把自己转化为一系列字节,记录字节的状态数据,以便再次利用的这个过程)

    20.串行化(Serializable)是Java.io包中定义的一个接口。这个接口中没有定义任何方法,只是一个特殊的标记,用来告诉编译器,这个对象参加了串行化的协议,可以把它串行化。一个类要具有可串行化的特性就必须实现接口Java.io.Serializable。

    21.有些对象不能串行化,例如Thread对象,FileInputStream对象以及FileOutputStream对象等,因为其状态是暂时的。

    22.对不希望串行化的对象要用关键字transient修饰。

    23.创建管道输入流对象(PipeInputStream):

    public PipeInputStream();
    public PipeInputStream(PipeOutputStream src);
    

    24.创建管道输出流对象(PipeOutputStream):

    public PipeOutputStream();
    public PipeOutputStream(PipeInputStream src)
    

    25.被连接的管道流必须没有与任何别的管道流连接,否则会抛出IOException异常,管t道输出流是往管道中写数据,管道输入流是往管道中读数据。(类似文件和文件流的关系)因为InputStream本来就是字节输入流,InputStream对应的字符流是Reader类。

    26.InputStreamReader类继承自Reader类,通过其read方法从字节流中读取一个或者多个字节数据转换为字符数据。它可以接一个缓冲流来提高效率。OutputStreamWriter同理。

    27.InputStream构造方法摘要 :出处

    1)InputStreamReader (InputStream  in)  创建一个使用默认字符集的 InputStreamReader。 
    2)InputStreamReader (InputStream  in, Charset  cs)  创建使用给定字符集的 InputStreamReader。 
    3)InputStreamReader (InputStream  in, CharsetDecoder  dec)   创建使用给定字符集解码器的 InputStreamReader。 
    4)InputStreamReader (InputStream  in, String  charsetName)  创建使用指定字符集的 InputStreamReader。
    

    28.一种高效的写法:

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    

    29.与InputStreamReader是字节转字符不同,OutputStreamWriter是字符转字节。反正外界传进来是字节,往外界输出的也是字节。

    30.BufferReader的两个构造方法:

    BufferedReader(Reader in);
    BufferedReader(Reader in,int size);
    

    31.小结:
    1)File,FileStream是处理本地文件的类
    2)DataStream是一个过滤流的子类,借此可以读写各种基本数据。
    3)BufferedStream的作用是在数据送到目的地之前先缓存,达到一定数量时再送到目的地,以提高程序的运行效率。
    4)PipedStream适合于一个处理的输出作为另一个处理的输入的情况。

    LAB11(文件读写):
    1.FileInputStream(文件输入流)是从系统的某个文件中获得输入字节
    FileOutputStream(File file)是向File对象的文件写入数据

    2.无参的read()方法返回int类型,返回值是数据下一个字节的字节码,如果已到达流的最后面了,就返回-1;带参数的read()方法返回的是读取的字节数(到达数据的末端返回值为-1)

    3.read()源码:

    //带参
        public int read(byte b[], int off, int len) throws IOException {
        //这里是一些前期判断,我们的buffer[]数组不能为空,偏移量一开始不能比0小,要读取的字节长度也不能比0小
            if (b == null) {
                throw new NullPointerException();
            } else if (off < 0 || len < 0 || len > b.length - off) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
    
            int c = read();
            if (c == -1) {
                return -1;
            }
            b[off] = (byte)c;
    
            int i = 1;
            try {
                for (; i < len ; i++) {
                    c = read();
                    if (c == -1) {
                        break;
                    }
                    b[off + i] = (byte)c;
                }
            } catch (IOException ee) {
            }
            return i;
        }
        //--------------------分割线--------------------------
        public int read(byte b[]) throws IOException {
            return read(b, 0, b.length);
        }
    
    //不带参
    /**
         * Reads the next byte of data from the input stream. The value byte is
         * returned as an <code>int</code> in the range <code>0</code> to
         * <code>255</code>. If no byte is available because the end of the stream
         * has been reached, the value <code>-1</code> is returned. This method
         * blocks until input data is available, the end of the stream is detected,
         * or an exception is thrown.
         *
         * <p> A subclass must provide an implementation of this method.
         *
         * @return     the next byte of data, or <code>-1</code> if the end of the
         *             stream is reached.
         * @exception  IOException  if an I/O error occurs.
         */
        public abstract int read() throws IOException;
    

    4.用FileInputStream向文件中写入内容的步骤:
    1)建立File对象:File in=new File(String pathname)
    2)构造字符串:String text=“XXXXX”
    3)字符串转byte,并指定编码方式:byte[] a=text.getBytes(“UTF-8”)
    4)建立文件输出流:FileOutputStream o=new FileOutputStream(File filename)
    5)开始写入:o.write(a)
    6)关闭输出流:o.close()

    5.删除String中的特定字符串:用replace方法即可,把待删除字符串替换成""即可达到删除字符串的目的。

    6.获取子字符串:String.subString(int beginindex,int endindex),endindex表示子字符串在原字符串中的结束位置,也就是’\0’的位置。这个方法还可以用来拼接字符串,从而实现删除特定位置字符串的目的。

    7.FileReader介绍:
    1)Reader类是定义Java的流式字符输入模式的抽象类。
    2)writer类是定义流式字符输出的抽象类
    3)FileReader类创建了一个可以读取文件内容的Reader类
    4)FileWriter创建一个可以写文件的Writer类
    用FileReader类写文件示例:

      import  java.io.*;
    
        class FileWriterDemo {
    
            public static void  main (String args[ ]) throws Exception {
    
                String source = "learn how to write to file";
    
                FileWriter  f1 = new FileWriter("file1.txt");
    
                for  (int i=0; i<buffer.length; i +=2) {
    
                    f1.write (buffer[i]);
    
                 }
    
                fo.close();
    
                 FileWriter f2 = new FileWriter("file2.txt");
    
                f2.write(buffer);
    
                f2.close();
    
                FileWriter  f3 = new FileWriter ("file3.txt");
    
                f2.write(buffer,buffer.length-buffer.length/4, buffer.length/4);
    
            }
    
    }
    

    8.用FileWriter.write(String)向文件中写入字符串时,如果字符串中有换行,那么构造这个字符串的时候你得在换行符\n前加一个\r,因为在Windows系统里面\r\n才是换行

    9.解决读取文件时乱码问题:先FileInputStream,然后InputStreamReader,最后是BufferedReader,就是文件–》按字节读取–》按流读取

    public static void copyFile (String sourceFile, String targetFile) throws IOException {
            FileWriter fw_o=new FileWriter(targetFile);
            FileInputStream fis=new FileInputStream(sourceFile);
            InputStreamReader fr=new InputStreamReader(fis,"gbk");//重点是这个,我也不知道为什么用utf-8不行
            BufferedReader br=new BufferedReader(fr);
            BufferedWriter bw=new BufferedWriter(fw_o);
            String s=new String();
            int i=0;
            while ((s=br.readLine())!=null){
                System.out.println(s);
                bw.write(s);
                bw.newLine();
            }
            bw.close();
        }
    

    原文件内容:
    在这里插入图片描述
    运行输出:
    在这里插入图片描述

    展开全文
  • C语言文件读写函数总结

    千次阅读 多人点赞 2018-04-30 23:51:59
    一、字符读写 1、字符写入文件函数 fputc 2、从文件中读取字符 fgetc 二、字符串的读写 1、字符串写入文件函数 fputs 2、从文件中读取字符 fgets 三、块数据读写 1、向文件中写入块数据fwrite 2、从文件中...

    一、字符读写

    1、字符写入文件函数 fputc

    fputc函数的原型如下:
    
        int fputc( int c, FILE *fp );
    
    参数说明:
        其中,c是要写入的字节,它虽被定义为整型,但只使用最低位的一字节,fp是文件指针。
    
    fputc的功能:
        将字节c输出至fp所指向的文件。如果成功,位置指针自动后 移1字节的位置,并且返回c;否则返回EOF。
    

     

    2、从文件中读取字符 fgetc

    fgetc函数的原型如下:
    
        int fgetc( FILE *fp );
    
    参数说明:
        其中fp为文件指针。
    
    fgetc的功能:
        从fp所指向的文件中读取一个字节,如果成功则返回读取的字节,位置指针自动后移1字节的位置;否则返回EOF。

     

    二、字符串的读写

    1、字符串写入文件函数 fputs

    fputs函数的原型如下:
    
        int fputs( const char *s, FILE *fp );
    
    参数说明:
        其中,s是要写入的字符串,fp是文件指针。
    
    fputs的功能:
        将字符串s输出至fp所指向的文件(不含'\0')。如果成功,位置指针自动后移,函数返回一个非负整数;否则返回EOF。

     

    2、从文件中读取字符 fgets

    fgets函数的原型如下:
    
        char *fgets( char *s, int n, FILE *fp );
    
    参数说明:
        其中,s指向待赋值字符串的首地址,n是控制读取个数的参数,fp为文件指针。 
    
    fgets的功能:
        从位置指针开始读取 一行或n-1个字符,并存入s,存储时自动在字符串结尾加上'\0'。如果函数执行成功,位置指针自动后移,
    并返回s的值,否则返回NULL。

     

    三、块数据读写

    所谓块读写,就是读写n块以m个字节为单位的二进制数据,可以是一个字符(一个字符为一字节,则块大小为1*1),可以是一个长度为n字符串(块大小1*n),可以是长度为n的整型数组(整型以4字节算,块大小4*n),也可以是结构体等任意数据类型,并没有什么限制。

    1、向文件中写入块数据fwrite

    fwrite函数的原型如下:
    
        size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );
    
    参数说明:
        ptr:指向保存读写数据的内存的指针,它可以指向数组、变量、结构体等。
        size:表示每个数据块的字节数。
        count:表示要读写的数据块的块数。
        fp:表示文件指针。
        理论上,每次读写 size*count 个字节的数据。
    
    fwrite的功能:
        从内存中的ptr指向的地址开始,将连续n*size字节的内容写入fp文件中。该函数的返回值是实际写入的数据块个数。

     

    2、从文件中读取块数据fread

    fread函数的原型如下:
    
        size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
    //size_t 是在 stddef.h 头文件中使用 typedef 定义的数据类型,表示无符号整数,也即非负数,常用来表示数量。
    
    参数说明:
        见fwrite
    
    fread的功能:
        从文件fp中,连续读取n*size字节的内容,并存入ptr指向的内存空间。该函数的返回值是实际读入的数据块个数。

     

    四、格式化读写

    格式化读写函数包括fprintf和fscanf两个函数,它们只用于文本文件的读写,不能用于二进制文件的读写。文本文件与二进制文件的区别下面注意点中有介绍。

    1、格式化写入文件fprintf

    fprintf函数的原型如下:
    
        int fprintf( FILE *fp, const char* format, 输出参数1, 输出参数2… );
    
    参数说明:
        其中,fp是文件指针,format为格式控制字符串,输出参数列表为待输出的数据。 
    
    fprintf的功能:
        根据指定的格式(format参数)发送数据(输出参数)到文件fp。

    例:

    #include <stdio.h>
      
    int main()
    {
        FILE *fp;
        fp = fopen("a.txt","w");
        int a = 10;
        double f = 11.11;
        fprintf(fp, "%d%lf", a, f);
        fclose(fp);
        return 0;
    }
    
    注意:fprintf()按格式输入到流,其用法和printf()相同,不过不是写到控制台,而是写到流罢了。注意的是
    返回值为此次操作写入到文件的字节数。如int c =fprintf(fp, "%s %s %d %f", str1,str2, a, b) ;
    假设str1:10字节;str2:10字节;a:2字节;b:8字节;则最终c为33,因为写入时不同的数据间自动加入一个空格。

     

    2、从文件中格式化读取fscanf

    fscanf函数的原型如下:
    
        int fscanf( FILE *fp,  const char* format, 地址1,地址2… );
    
    函数说明:
        其中,fp是文件指针,format为格式控制字符串,地址列表为输入数据的存放地址。 
    
    fscanf的功能:
        根据指定的格式(format参数)从文件fp中读取数据至内存(地址)。

    例:

    #include <stdio.h>
      
    int main()
    {
        FILE *fp;   
        fp = fopen("a.txt","r"); //需要创建a.txt文件,然后写入两个数据,空格隔开
        int i=0;
        double f=0;
        fscanf( fp, "%d%lf", &i, &f );
        fclose(fp);
        printf("%d\n%lf\n",i,f);
        return 0;
    }
    

    五、一些注意点

    (上面的都是网上抄的,下面的是我自己总结的,大佬们有砖的话轻点拍)

    1、fputc和fgetc注意点

    fputc 每次只能存一个字节,如果将整型、浮点型等数据类型入文件(因为整型浮点型每个数据都需要好几个字节,由于平台不同不固定,具体自己查不列出),就会造成数据只截取最后一个字节导致数据出错;同理fgetc每次也只能读取一个字节。这时用 fprintf 和 fscanf 函数格式化读写比较合适。

    fgetc 每次调用只能获取一个字节,如果是中文字符,utf8 编码会占用三个字节,因此要用 fgets 来读取。当然你不嫌累也可以用 fgetc 读三次,然后拼成一个中文字符。

     

    2、fputs和fgets注意点

    fgets 有局限性,每次最多只能从文件中读取一行内容,因为 fgets 遇到换行符就结束读取。如果希望读取多行内容,需要使用 fread 函数;相应地写入函数为 fwrite。

     

    3、fwrite和fread注意点

    fwrite和fread直接读写二进制文本。

    Ⅰ、这里有人可能有疑问,二进制文件和文本文件有什么区别?

    参考:

    1、https://www.zhihu.com/question/19971994

    2、https://www.cnblogs.com/zhangjiankun/archive/2011/11/27/2265184.html

            直观上的区别是:文本文件打开后我们可以看懂,而二进制文件打开会是一堆“乱码”。但是,其实所有的文件在计算机中都是二进制,导致“乱码”是因为编码上不同。

            举个例子,比如在代码中的整型数65,用fwrite方式写入文件,我们打开文件时就会惊奇的发现,文件中并不是65,而是一个大写的 'A' 。而我们用fprintf却不会出现这个问题,65还是65。这是为什么呢?

            因为fwrite是直接将数据65写进了文件,而fprintf是将65拆成两个字符,‘6’和‘5’,‘6’和‘5’在ASCII编码表中分别是54和53,于是将54和53写进文件。写进文件后我们再来看打开文件时发生了什么?

            文件软件首先将文件中的数据读进内存,然后再将内存中的数据根据这个文本软件设置的编码格式(比如utf-8)进行解码。来看fwrite写入的文件,文件软件读到 '65' 后去编码表中找到对应数据,是 'A' 然后就将 'A' 输出到屏幕上;再看用fprintf写入的文件,文件软件读到 '54' 和 '53' 后去编码表中找到对应数据,是 '6' 和 '5' ,因此最终我们在屏幕上看到的是65。

            更详细的解释去看我发的参考链接,可能讲的更清楚。

    注:上面直观上的区别说法不是很准确。当读写采用不同编码表时就会产生乱码,比如你是以utf-8格式写入文件,然后将文件软件换个编码格式,比如 "GB2312" ,这时再打开也会是乱码,根本原因是相同的字符在不同编码中的编号是不同的,比如 "你" 字,"utf-8" 中的编码为e4 bd a0,而在 "GB2312" 中的编码为 c4 e3,你用e4 bd a0在 "GB2312" 为编码下打开,就会在 "GB2312" 中去找对应的字符,那么当然不会是 "你" 字了,也就会产生乱码。

     

    Ⅱ、fopen函数中以文本方式与二进制方式打开文件的区别

    参考:https://blog.csdn.net/recsysml/article/details/44195793

    a、Windows平台下 
    如果以“文本”方式打开文件,当读取文件的时候,系统会将所有的"/r/n"转换成"/n";当写入文件的时候,系统会将"/n"转换成"/r/n"写入。 
    如果以"二进制"方式打开文件,则读/写都不会进行这样的转换。 

    b、在Unix/Linux平台下

    “文本”与“二进制”模式没有区别。

    读写二进制文件,在fopen函数中mode的参数要加上“b”,用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux下会忽略该字符。

     

    Ⅲ、了解了文本方式与二进制方式区别我们来总结一下分别是哪些函数使用

    a、文本方式读写:fprintf/fscanf

    b、二进制方式读写:fgetc/fputc、fgets/fputs、fread/fwrite

     

    另:fwrite/fread与write/read的区别:

    https://blog.csdn.net/ljlstart/article/details/49535005

     

    4、fprintf和fscanf注意点

    fscanf将读取的ascii码转换成二进制放到内存中,效率略低;fgetc fputc 都是按照字节存取,无论文本模式还是二进制模式打开,都按照一个一个字节读取,不存在\r\n问题。

    还有一点是很多网站中文转utf-8的编码转换,utf-8编码是错的,它上面其实显示出来的是unicode编码,把我搞混好长时间。

     

     

    六、代码实例

    附上我的测试实例,有空的话自己打开一个个开关,编译运行看是否符合自己预期

    #include <stdio.h>
    #include <string.h>
    
    typedef struct 
    {
        char str1[6];
        char str2[6];
        char str3[6];    
    }STRS;
    
    
    int main()
    {
        FILE *fp;
        /*
         * fputc
         */
    
    #if 0
        fp = fopen("a.txt","w");
        //char a[3] = "你";
        //fputc(a[0],fp);
        //fputc(a[1],fp);
        //fputc(a[2],fp);
        int a=33;
        fputc(a,fp);
        fclose(fp);
    #endif
    
        /*
         * fgetc
         */
    
    #if 0 
        fp = fopen("a.txt","r");
        char c1 = fgetc(fp);
        char c2 = fgetc(fp);
        fclose(fp);
        printf("%c\n%c\n",c1,c2);
    #endif
    
        /*
         * fputs
         */
        
    #if 0
        fp = fopen("b.txt","w");
        char *s = "你好";
        fputs(s, fp);
        fclose(fp);
    #endif
    
        /*
         * fgets
         */
    
    #if 0
        fp = fopen("b.txt","r");
        STRS Strs;
        STRS *strs = &Strs;
    	    
        char hello1[6] = "hello";
        char hello3[6] = {'n','i','h','a','o'};
     
        memset(strs->str1,0,6);
        memcpy(strs->str1,hello1,6);
        memset(strs->str3,0,6);
        memcpy(strs->str3,hello3,6);
        //注意1:fgetc只能获取一位char字符,如果是中文字符,需要占三位char字符,因此要用fgets来读取;
        //注意2:读取的数据的长度要小于等于字符数组长度-1,因为字符串最后要存放'\0'。例如现在str2的长度为6,就会导致strs->str2最后不能加上‘\0’,从而会越界,连带输出str3,最终输出你好hello
        memset(strs->str2,0,6);
        fgets(strs->str2,7,fp);
        
        memset(strs->str3,0,6);
        memcpy(strs->str3,hello3,6);
        
        printf("%s\n",strs->str2);
        fclose(fp);
    #endif
    
        /*
         * fprintf
         */
    
    #if 0
        fp = fopen("c.txt","w");
        int b = 65;
        //double f = 1.11;
        //char s[3] = "你";
        //fprintf(fp, "%s", s);
        fprintf(fp, "%d", b);
        //fprintf(fp, "%d %lf", a, f);
        fclose(fp);
    #endif
    
        /*
         * fscanf
         */
    
    #if 0
        fp = fopen("c.txt","r+"); //需要创建a.txt文件,然后写入两个数据,空格隔开
        //int i=0;
        //double f=0;
        //fscanf( fp, "%d%lf", &i, &f );
        //printf("%d\n%lf\n",i,f);
        char c;
        fscanf( fp, "%c", &c);
        printf("%c\n",c);
        fclose(fp);
        
        fp = fopen("c.txt","r+");
        int fscanf_int;
        fscanf( fp, "%d", &fscanf_int );
        printf("%d",fscanf_int);
        fclose(fp);
    #endif
    #if 0
        fp = fopen("e.txt","r");
        double a = 0;
        fscanf( fp, "%lf", &a);
        fclose(fp);
        printf("%lf\n",a);
    #endif
         
        /*
         * fwrite
         */
        
    #if 0
        fp = fopen("e.txt","wb");
        //char array[3] = "你";
        //fwrite(array, sizeof(char), 3, fp);
        //double array[3] = {1.11, 2.22, 3.33};
        //fwrite(array, sizeof(double), 3, fp);
        //double a = 3.14159;
        //fwrite(&a, sizeof(double), 1, fp);
        char a=65;
        fwrite(&a, sizeof(char), 1, fp);
        fclose(fp);
    #endif
    
        /*
         * fread
         */
        
        /*
        fp = fopen("e.txt","rb");
        double array[3];
        fread(array, sizeof(double), 3,fp);
        fclose(fp);
        for(int i=0;i<3;i++)
        {
    	printf("%lf\n",array[i]);
        }
        */
    
        return 0;
    }

     

    展开全文
  • 代码shutil.copyfile(os.path.join(sourcepath+'/'+eachclass+'/...访问后一个路径上的文件valpath+'/'+eachclass+'/'+im,im是一个*.jpg图片,出现permission denied错误 原因分析:这个路径是jupter notebook默认...
  • java文件读写

    万次阅读 2019-04-04 17:23:35
    单方向:只能从一个方向流向另一个方向:要么是读,要么是写,不能在同一个流中读写并行。 那么想要既读又写,就需要开两个流。 例如:System.out.println()中的out就是一个可以用来做输出的流。 InputStream:从...
  • c++文件读写操作

    万次阅读 多人点赞 2018-04-17 11:07:00
    近期适配几款游戏的数据,因为重复量太大,因此写一个对数据进行处理的程序,下面是整个...fstream提供了三个类,用来实现c++对文件的操作(文件的创建、读、写) ifstream -- 从已有的文件读入 ofstream -- 向...
  • MATLAB03:数据类型与文件读写

    万次阅读 多人点赞 2019-11-14 13:13:44
    文章目录MATLAB03:数据类型与文件读取数据类型数值类型(numeric)字符串类型(char)结构体(structure)结构体的基本使用结构体的常用函数元胞数组(cell)元胞数组的基本使用元胞数组的常用函数高维元胞数组判断变量数据...
  • c++文件读写

    千次阅读 2019-08-12 23:33:30
    //文件读写 using namespace std; void test() { //地址中的斜杠要么写双反斜杠,要么写单正斜杠 char sourceName[] = "C:\\Users\\Polaris\\Desktop\\source.txt"; //源文件地址 char ...
  • Android文件读写权限

    万次阅读 2019-04-24 10:45:46
    首先需要在manifest中添加静态权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>...
  • 测试nfs文件读写速度

    千次阅读 2018-11-10 09:42:59
    luther@gliethttp:~$ time dd if=/dev/zero of=/nfs/testfile bs=8k count=1024 这是来测试nfs写  luther@gliethttp:~$ time dd if=/nfs/testfile of=/dev/null bs=8k count=1024 这是测试nfs读
  • go文件读写json文件

    千次阅读 2019-02-14 10:43:38
    package main import ( "encoding/json" "fmt" "log" "os" ) type User struct { Name string Age int8 } func testMarshal() []byte { ... data, err := ...
  • c语言文件读写操作

    千次阅读 2019-03-20 20:15:35
    当使用打开函数时,必须给出文件名、文件操作方式(读、写或读写),如果该文件名不存在,就意味着建立(只对写文件而言,对读文件则出错),并将文件指针指向文件开头。若已有一个同名文件存在,则删除该文件,若无同名...
  • c 文件读写

    千次阅读 2019-01-30 14:50:30
    c 文件读写  一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节。C 语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件。 打开文件  格式:  FILE *fopen( const ...
  • Android 文件读写最全解析

    千次阅读 多人点赞 2020-04-21 18:08:19
    本文目录文件读写概述读取raw目录文件读取assets目录文件data/data/(包名) 目录文件读写写数据读数据sdcard文件读写申请动态权限写数据读数据完整代码 文件读写概述 raw下的和assert下的文件可以以资源文件的形式...
  • 文件读写时,read write fread fwrite都可以实现,如果文件很大,耗时就特别长。 内存映射和分页读写可以解决这个问题,小弟对于读操作没疑问,对于写就有一个难题: 举例: 一个文件分成n页,我获取了第2页的内容...
  • MAC10.15文件读写权限

    千次阅读 2020-05-09 09:45:35
    起因 创建文件夹报错: mkdir /data/logs/2020-05-09 mkdir: /data/logs/2020-05-09: Read-only file system 原因 由于10.15系统原因,SIP用来保护系统不被第三方软件修改,导致的 具体操作 1.关闭sip:参考链接 ...
  • 1、读取dxf文件的思路 新建DxfDocument对象-调用Load方法读取对应地址的dxf文件并保存在新建的DxfDocument对象中-从新建的DxfDocument对象中读取对应的元素 读取dxf文件: DxfDocument dxf = DxfDocument.Load(...
  • linux下文件读写

    千次阅读 2019-06-23 10:25:26
    linux 下一切皆文件 文件读写 文件的打开open函数 涉及头文件: ubuntu 头文件所在目录:/usr/include/x86_64-linux-gnu/sys #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> ...
  • 21. Perl 文件操作-文件读写

    千次阅读 2019-08-27 16:03:27
    perl 程序通过文件句柄对文件进行文件读写 文件句柄相当于一个指针, 指向这个文件; 定义文件句柄有两种方式: 一种是会名称全部时大写, 另一种时是定位为标量, 笔者建议句柄使用标量, 因为perl默认的文件句柄为全部...
  • Linux监控文件读写

    千次阅读 2019-07-25 17:18:34
    如何去监测目标文件, 我思考了很久仍没有头绪,翻了翻开发大赛入围名单, 发现马艺诚同学使用了hook方法来监测进程操作目标文件。于是下午试了试, 确实可行(毕竟人家已经做出来了嘛)。下面讲解一下我下午尝试的...
  • Android Studio文件读写操作

    千次阅读 2020-04-28 12:14:56
    Android Studio文件读写操作 自己学习记录,以便后续复习和查找。大神飘过! 直接上代码 读代码: public String read(){ FileInputStream in=null; BufferedReader reader=null; StringBuilder content=new ...
  • Python文件读写模式

    千次阅读 2019-05-27 19:57:32
    文件常见的读写模式 w 以写方式打开, W 文件若存在,首先要清空,然后(重新)创建 a 以追加模式打开 (从 EOF 开始, 必要时创建新文件) r+ 以读写模式打开 w+ 以读写模式打开 (参见 w ) a+ 以...

空空如也

1 2 3 4 5 ... 20
收藏数 97,889
精华内容 39,155
关键字:

文件读写