精华内容
下载资源
问答
  • 2020-11-24 12:41:23

    此文为转载 ,如需原始作者要求删除请私信我

    计算机的存储系统采用Register,Cache,Memory和I/O的方式来构成存储系统,无疑是一个性能和经济性的妥协的产物。Cache和Memory机制是计算机硬件的基础内容,这里就不再啰嗦。下面重点说明Write-back,Write-through及write allocate这三种操作的区别。

           一、CPU读Cache

               1. Read through,即直接从内存中读取数据;

               2. Read allocate,先把数据读取到Cache中,再从Cache中读数据。

          二、CPU写Cache

              1. 若hit命中,有两种处理方式:

              Write-through: write is done synchronously both to the cache and to the backing store。Write-through(直写模式)在数据更新时,把数据同时写入Cache和后端存储。此模式的优点是操作简单;缺点是因为数据修改需要同时写入存储,数据写入速度较慢。

             Write-back (also called write-behind): initially, writing is done only to the cache. The write to the backing store is postponed until the cache blocks containing the data are about to be modified/replaced by new content。Write-back(回写模式)在数据更新时只写入缓存Cache。只在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储(即先把数据写到Cache中,再通过flush方式写入到内存中)。此模式的优点是数据写入速度快,因为不需要写存储;缺点是一旦更新后的数据未被写入存储时出现系统掉电的情况,数据将无法找回。         

              2. 若miss,有两种处理方式:

              Write allocate (also called fetch on write): data at the missed-write location is loaded to cache, followed by a write-hit operation. In this approach, write misses are similar to read misses.。Write allocate:先把要写的数据载入到Cache中,写Cache,然后再通过flush方式写入到内存中;  写缺失操作与读缺失操作类似。      

              No-write allocate (also called write-no-allocate or write around): data at the missed-write location is not loaded to cache, and is written directly to the backing store. In this approach, only the reads are being cached。No write allocate:并不将写入位置读入缓存,直接把要写的数据写入到内存中。这种方式下,只有读操作会被缓存。

    更多相关内容
  • Python serial.write方法代码示例

    千次阅读 2020-12-09 04:37:40
    本文整理汇总了Python中serial.write方法的典型用法代码示例。如果您正苦于以下问题:Python serial.write方法的具体用法?Python serial.write怎么用?Python serial.write使用的例子?那么恭喜您, 这里精选的方法...

    本文整理汇总了Python中serial.write方法的典型用法代码示例。如果您正苦于以下问题:Python serial.write方法的具体用法?Python serial.write怎么用?Python serial.write使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在模块serial的用法示例。

    在下文中一共展示了serial.write方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Python代码示例。

    示例1: __checkType__

    ​点赞 5

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def __checkType__(self, serial):

    byte = serial.read().decode("utf-8")

    print(byte)

    if byte == "1":

    print("??? ???? ?? : " + serial.port)

    serial.write(b'0')

    self.threads["Sensor"] = SensorThread(serial)

    return self.threads["Sensor"]

    elif byte == "2" :

    print("??? ???? ?? : " + serial.port)

    serial.write(b'0')

    self.threads["Control"] = ControlThread(serial)

    return self.threads["Control"]

    else :

    print("? ? ?? ???? : " + serial.port)

    serial.write(b'1')

    return None

    #?? ???

    开发者ID:toy0605,项目名称:Hydroponics,代码行数:21,

    示例2: write

    ​点赞 4

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def write(self, data):

    """\

    Output the given byte string over the serial port. Can block if the

    connection is blocked. May raise SerialException if the connection is

    closed.

    """

    if not self.is_open:

    raise portNotOpenError

    with self._write_lock:

    try:

    self._socket.sendall(to_bytes(data).replace(IAC, IAC_DOUBLED))

    except socket.error as e:

    raise SerialException("connection failed (socket error): %s" % (e,))

    return len(data)

    开发者ID:sketchpunk,项目名称:android3dblendermouse,代码行数:16,

    示例3: write

    ​点赞 3

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def write(self, value):

    print(value)

    if(value == 0):

    serial.write('0')

    elif(value == 1):

    serial.write('1')

    elif(value == 2):

    serial.write('2')

    elif(value == 3):

    serial.write('3')

    elif(value == 4):

    serial.write('4')

    # Disconnects the Arduino

    开发者ID:ThermoNuclearPanda,项目名称:Project_Automail,代码行数:16,

    示例4: showReady

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def showReady(self):

    serial.write('6')

    开发者ID:ThermoNuclearPanda,项目名称:Project_Automail,代码行数:4,

    示例5: _internal_raw_write

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def _internal_raw_write(self, data):

    """internal socket write with no data escaping. used to send telnet stuff."""

    with self._write_lock:

    self._socket.sendall(data)

    开发者ID:sketchpunk,项目名称:android3dblendermouse,代码行数:6,

    示例6: telnetSendOption

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def telnetSendOption(self, action, option):

    """Send DO, DONT, WILL, WONT."""

    self.connection.write(to_bytes([IAC, action, option]))

    开发者ID:sketchpunk,项目名称:android3dblendermouse,代码行数:5,

    示例7: rfc2217SendSubnegotiation

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def rfc2217SendSubnegotiation(self, option, value=b''):

    """Subnegotiation of RFC 2217 parameters."""

    value = value.replace(IAC, IAC_DOUBLED)

    self.connection.write(to_bytes([IAC, SB, COM_PORT_OPTION, option] + list(value) + [IAC, SE]))

    # - check modem lines, needs to be called periodically from user to

    # establish polling

    开发者ID:sketchpunk,项目名称:android3dblendermouse,代码行数:9,

    示例8: write

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def write(self, data):

    """\

    Output the given byte string over the serial port. Can block if the

    connection is blocked. May raise SerialException if the connection is

    closed.

    """

    if not self.is_open:

    raise portNotOpenError

    with self._write_lock:

    try:

    self._socket.sendall(to_bytes(data).replace(IAC, IAC_DOUBLED))

    except socket.error as e:

    raise SerialException("connection failed (socket error): {}".format(e))

    return len(data)

    开发者ID:arpruss,项目名称:gcodeplot,代码行数:16,

    示例9: telnet_send_option

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def telnet_send_option(self, action, option):

    """Send DO, DONT, WILL, WONT."""

    self.connection.write(to_bytes([IAC, action, option]))

    开发者ID:arpruss,项目名称:gcodeplot,代码行数:5,

    示例10: rfc2217_send_subnegotiation

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def rfc2217_send_subnegotiation(self, option, value=b''):

    """Subnegotiation of RFC 2217 parameters."""

    value = value.replace(IAC, IAC_DOUBLED)

    self.connection.write(to_bytes([IAC, SB, COM_PORT_OPTION, option] + list(value) + [IAC, SE]))

    # - check modem lines, needs to be called periodically from user to

    # establish polling

    开发者ID:arpruss,项目名称:gcodeplot,代码行数:9,

    示例11: telnet_send_option

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def telnet_send_option(self, action, option):

    """Send DO, DONT, WILL, WONT."""

    self.connection.write(IAC + action + option)

    开发者ID:whaleygeek,项目名称:bitio,代码行数:5,

    示例12: rfc2217_send_subnegotiation

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def rfc2217_send_subnegotiation(self, option, value=b''):

    """Subnegotiation of RFC 2217 parameters."""

    value = value.replace(IAC, IAC_DOUBLED)

    self.connection.write(IAC + SB + COM_PORT_OPTION + option + value + IAC + SE)

    # - check modem lines, needs to be called periodically from user to

    # establish polling

    开发者ID:whaleygeek,项目名称:bitio,代码行数:9,

    示例13: filter

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def filter(self, data):

    """\

    Handle a bunch of incoming bytes. This is a generator. It will yield

    all characters not of interest for Telnet/RFC 2217.

    The idea is that the reader thread pushes data from the socket through

    this filter:

    for byte in filter(socket.recv(1024)):

    # do things like CR/LF conversion/whatever

    # and write data to the serial port

    serial.write(byte)

    (socket error handling code left as exercise for the reader)

    """

    for byte in iterbytes(data):

    if self.mode == M_NORMAL:

    # interpret as command or as data

    if byte == IAC:

    self.mode = M_IAC_SEEN

    else:

    # store data in sub option buffer or pass it to our

    # consumer depending on state

    if self.suboption is not None:

    self.suboption += byte

    else:

    yield byte

    elif self.mode == M_IAC_SEEN:

    if byte == IAC:

    # interpret as command doubled -> insert character

    # itself

    if self.suboption is not None:

    self.suboption += byte

    else:

    yield byte

    self.mode = M_NORMAL

    elif byte == SB:

    # sub option start

    self.suboption = bytearray()

    self.mode = M_NORMAL

    elif byte == SE:

    # sub option end -> process it now

    self._telnetProcessSubnegotiation(bytes(self.suboption))

    self.suboption = None

    self.mode = M_NORMAL

    elif byte in (DO, DONT, WILL, WONT):

    # negotiation

    self.telnet_command = byte

    self.mode = M_NEGOTIATE

    else:

    # other telnet commands

    self._telnetProcessCommand(byte)

    self.mode = M_NORMAL

    elif self.mode == M_NEGOTIATE: # DO, DONT, WILL, WONT was received, option now following

    self._telnetNegotiateOption(self.telnet_command, byte)

    self.mode = M_NORMAL

    # - incoming telnet commands and options

    开发者ID:sketchpunk,项目名称:android3dblendermouse,代码行数:60,

    示例14: filter

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def filter(self, data):

    """\

    Handle a bunch of incoming bytes. This is a generator. It will yield

    all characters not of interest for Telnet/RFC 2217.

    The idea is that the reader thread pushes data from the socket through

    this filter:

    for byte in filter(socket.recv(1024)):

    # do things like CR/LF conversion/whatever

    # and write data to the serial port

    serial.write(byte)

    (socket error handling code left as exercise for the reader)

    """

    for byte in iterbytes(data):

    if self.mode == M_NORMAL:

    # interpret as command or as data

    if byte == IAC:

    self.mode = M_IAC_SEEN

    else:

    # store data in sub option buffer or pass it to our

    # consumer depending on state

    if self.suboption is not None:

    self.suboption += byte

    else:

    yield byte

    elif self.mode == M_IAC_SEEN:

    if byte == IAC:

    # interpret as command doubled -> insert character

    # itself

    if self.suboption is not None:

    self.suboption += byte

    else:

    yield byte

    self.mode = M_NORMAL

    elif byte == SB:

    # sub option start

    self.suboption = bytearray()

    self.mode = M_NORMAL

    elif byte == SE:

    # sub option end -> process it now

    self._telnet_process_subnegotiation(bytes(self.suboption))

    self.suboption = None

    self.mode = M_NORMAL

    elif byte in (DO, DONT, WILL, WONT):

    # negotiation

    self.telnet_command = byte

    self.mode = M_NEGOTIATE

    else:

    # other telnet commands

    self._telnet_process_command(byte)

    self.mode = M_NORMAL

    elif self.mode == M_NEGOTIATE: # DO, DONT, WILL, WONT was received, option now following

    self._telnet_negotiate_option(self.telnet_command, byte)

    self.mode = M_NORMAL

    # - incoming telnet commands and options

    开发者ID:arpruss,项目名称:gcodeplot,代码行数:60,

    示例15: run

    ​点赞 2

    # 需要导入模块: import serial [as 别名]

    # 或者: from serial import write [as 别名]

    def run(self):

    if self.log.fan_out == True :

    jsonString = json.dumps({ "Comm" : "onFan" })

    self.serial.write(bytes(jsonString, encoding="utf-8"))

    else :

    jsonString = json.dumps({ "Comm" : "offFan" })

    self.serial.write(bytes(jsonString, encoding="utf-8"))

    self.serial.write(b'\n')

    byte = self.serial.read().decode("utf-8")

    print(byte)

    if byte == "0" :

    print("?? ?? ??")

    else :

    print("?? ?? ??")

    if self.log.humidifier == True :

    jsonString = json.dumps({ "Comm" : "onHumidifier" })

    self.serial.write(bytes(jsonString, encoding="utf-8"))

    else :

    jsonString = json.dumps({ "Comm" : "offHumidifier" })

    self.serial.write(bytes(jsonString, encoding="utf-8"))

    self.serial.write(b'\n')

    byte = self.serial.read().decode("utf-8")

    print(byte)

    if byte == "0" :

    print("?? ?? ??")

    else :

    print("?? ?? ??")

    if self.log.peltier == True :

    jsonString = json.dumps({ "Comm" : "onPeltier" })

    self.serial.write(bytes(jsonString, encoding="utf-8"))

    else :

    jsonString = json.dumps({ "Comm" : "offPeltier" })

    self.serial.write(bytes(jsonString, encoding="utf-8"))

    self.serial.write(b'\n')

    byte = self.serial.read().decode("utf-8")

    print(byte)

    if byte == "0" :

    print("?? ?? ??")

    else :

    print("?? ?? ??")

    开发者ID:toy0605,项目名称:Hydroponics,代码行数:48,

    注:本文中的serial.write方法示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。

    展开全文
  • FFmpeg在libavformat模块提供mux封装视频的API,包括avformat_write_header()写文件头、av_write_frame()写音视频帧、av_write_trailer()写文件尾。本文主要介绍写文件头的方法avformat_write_header()。通过分析...

    FFmpeg在libavformat模块提供mux封装视频的API,包括avformat_write_header()写文件头、av_write_frame()写音视频帧、av_write_trailer()写文件尾。本文主要介绍写文件头的方法avformat_write_header()。通过分析源码,与大家一起探讨FFmpeg是如何封装视频文件的。

    在libavformat/avformat.h有这三个API的描述:

     * The main API functions for muxing are avformat_write_header() for writing the
     * file header, av_write_frame() / av_interleaved_write_frame() for writing the
     * packets and av_write_trailer() for finalizing the file.
    
     * When the muxing context is fully set up, the caller must call
     * avformat_write_header() to initialize the muxer internals and write the file
     * header. Any muxer private options must be passed in the options parameter to 
     * this function.

    翻译如下:

    封装文件格式的主要API包括:avformat_write_header()写文件头,av_write_frame() / av_interleaved_write_frame()写音视频帧,av_write_trailer()写文件尾。当完全创建封装上下文后,必须调用avformat_write_header()来初始化封装器内部和写入文件头。任何封装器的私有选项必须通过选项参数传递到这个函数。

    avformat_write_header()函数声明位于libavformat/avformat.h:

    /**
     * Allocate the stream private data and write the stream header to
     * an output media file.
     *
     * @param s Media file handle, must be allocated with avformat_alloc_context().
     *          Its oformat field must be set to the desired output format;
     *          Its pb field must be set to an already opened AVIOContext.
     * @param options  An AVDictionary filled with AVFormatContext and muxer-private options.
     *                 On return this parameter will be destroyed and replaced with a dict containing
     *                 options that were not found. May be NULL.
     *
     * @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec had not already been fully initialized in avformat_init,
     *         AVSTREAM_INIT_IN_INIT_OUTPUT  on success if the codec had already been fully initialized in avformat_init,
     *         negative AVERROR on failure.
     *
     * @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_init_output.
     */
    av_warn_unused_result
    int avformat_write_header(AVFormatContext *s, AVDictionary **options);

    函数的实现位于libavformat/mux.c,具体如下:

    int avformat_write_header(AVFormatContext *s, AVDictionary **options)
    {
        int ret = 0;
        int already_initialized = s->internal->initialized;
        int streams_already_initialized = s->internal->streams_initialized;
    
        if (!already_initialized)
    		// 初始化输出
            if ((ret = avformat_init_output(s, options)) < 0)
                return ret;
    
        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
    		// 写入marker标识
            avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);
        if (s->oformat->write_header) {
    		// 写入文件头
            ret = s->oformat->write_header(s);
            if (ret >= 0 && s->pb && s->pb->error < 0)
                ret = s->pb->error;
            if (ret < 0)
                goto fail;
            flush_if_needed(s);
        }
        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
            avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);
    
        if (!s->internal->streams_initialized) {
    		// 初始化pts
            if ((ret = init_pts(s)) < 0)
                goto fail;
        }
    
        return streams_already_initialized;
    
    fail:
        deinit_muxer(s);
        return ret;
    }

    由此可见,avformat_write_header函数主要做4件事:

    1. 调用avformat_init_output()来初始化输出文件;
    2. 调用avio_write_marker()来写入marker标识,如果存在AVIOContext;
    3. 调用AVOutputFormat的write_header()来写入文件头;
    4. 调用init_pts()来初始化时间戳;

    我们来看下avformat_init_output()函数:

    int avformat_init_output(AVFormatContext *s, AVDictionary **options)
    {
        int ret = 0;
        if ((ret = init_muxer(s, options)) < 0)
            return ret;
    
        s->internal->initialized = 1;
        s->internal->streams_initialized = ret;
        if (s->oformat->init && ret) {
            if ((ret = init_pts(s)) < 0)
                return ret;
    
            return AVSTREAM_INIT_IN_INIT_OUTPUT;
        }
    
        return AVSTREAM_INIT_IN_WRITE_HEADER;
    }

    内部调用init_muxer()函数来初始化封装器:

    static int init_muxer(AVFormatContext *s, AVDictionary **options)
    {
        ......
        // 检查nb_streams是否为0
        if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
            av_log(s, AV_LOG_ERROR, "No streams to mux were specified\n");
            ret = AVERROR(EINVAL);
            goto fail;
        }
    
        for (i = 0; i < s->nb_streams; i++) {
            st  = s->streams[i];
            par = st->codecpar;
            // 检查timebase时间基,如果没有就设置默认时间基
            if (!st->time_base.num) {
                if (par->codec_type == AVMEDIA_TYPE_AUDIO && par->sample_rate)
                    avpriv_set_pts_info(st, 64, 1, par->sample_rate);
                else
                    avpriv_set_pts_info(st, 33, 1, 90000);
            }
    
            switch (par->codec_type) {
            case AVMEDIA_TYPE_AUDIO: // 检查音频采样率、block_align块对齐
                if (par->sample_rate <= 0) {
                    ret = AVERROR(EINVAL);
                    goto fail;
                }
                if (!par->block_align)
                    par->block_align = par->channels *
                                       av_get_bits_per_sample(par->codec_id) >> 3;
                break;
            case AVMEDIA_TYPE_VIDEO: // 检查视频宽高、宽高比
                if ((par->width <= 0 || par->height <= 0) &&
                    !(of->flags & AVFMT_NODIMENSIONS)) {
                    ret = AVERROR(EINVAL);
                    goto fail;
                }
                if (av_cmp_q(st->sample_aspect_ratio, par->sample_aspect_ratio)
                    && fabs(av_q2d(st->sample_aspect_ratio) - av_q2d(par->sample_aspect_ratio))
        			> 0.004*av_q2d(st->sample_aspect_ratio)) {
                    if (st->sample_aspect_ratio.num != 0 &&
                        st->sample_aspect_ratio.den != 0 &&
                        par->sample_aspect_ratio.num != 0 &&
                        par->sample_aspect_ratio.den != 0) {
                        ret = AVERROR(EINVAL);
                        goto fail;
                    }
                }
                break;
            }
    
            desc = avcodec_descriptor_get(par->codec_id);
            if (desc && desc->props & AV_CODEC_PROP_REORDER)
                st->internal->reorder = 1;
            st->internal->is_intra_only = ff_is_intra_only(par->codec_id);
    		// 检查codec_tag
            if (of->codec_tag) {
                if (   par->codec_tag
                    && par->codec_id == AV_CODEC_ID_RAWVIDEO
                    && (   av_codec_get_tag(of->codec_tag, par->codec_id) == 0
                        || av_codec_get_tag(of->codec_tag, par->codec_id) == MKTAG('r', 'a', 'w', ' '))
                    && !validate_codec_tag(s, st)) {
                    par->codec_tag = 0;
                }
                if (par->codec_tag) {
                    if (!validate_codec_tag(s, st)) {
                        const uint32_t otag = av_codec_get_tag(s->oformat->codec_tag, par->codec_id);
                        ret = AVERROR_INVALIDDATA;
                        goto fail;
                    }
                } else
                    par->codec_tag = av_codec_get_tag(of->codec_tag, par->codec_id);
            }
    
            if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT)
                s->internal->nb_interleaved_streams++;
        }
        // 检查priv_data
        if (!s->priv_data && of->priv_data_size > 0) {
            s->priv_data = av_mallocz(of->priv_data_size);
            if (!s->priv_data) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            if (of->priv_class) {
                *(const AVClass **)s->priv_data = of->priv_class;
                av_opt_set_defaults(s->priv_data);
                if ((ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
                    goto fail;
            }
        }
        // 设置encoder
        if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
            av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
        } else {
            av_dict_set(&s->metadata, "encoder", NULL, 0);
        }
        ......
        return 0;
    
    fail:
        av_dict_free(&tmp);
        return ret;
    }

    接着看s->oformat->write_header()函数,以mp4封装格式为例,位于libavformat/movenc.c。那么mp4对应的AVOutputFormat如下:

    AVOutputFormat ff_mp4_muxer = {
        .name              = "mp4",
        .long_name         = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
        .mime_type         = "video/mp4",
        .extensions        = "mp4",
        .priv_data_size    = sizeof(MOVMuxContext),
        .audio_codec       = AV_CODEC_ID_AAC,
        .video_codec       = CONFIG_LIBX264_ENCODER ?
                             AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
        .init              = mov_init,
        .write_header      = mov_write_header,
        .write_packet      = mov_write_packet,
        .write_trailer     = mov_write_trailer,
        .deinit            = mov_free,
        .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
        .codec_tag         = mp4_codec_tags_list,
        .check_bitstream   = mov_check_bitstream,
        .priv_class        = &mp4_muxer_class,
    };

    此时,write_header函数指针指向mov_write_header,具体函数如下:

    static int mov_write_header(AVFormatContext *s)
    {
        AVIOContext *pb = s->pb;
        MOVMuxContext *mov = s->priv_data;
        int i, ret, hint_track = 0, tmcd_track = 0, nb_tracks = s->nb_streams;
    
        if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
            nb_tracks++;
        if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
            hint_track = nb_tracks;
            for (i = 0; i < s->nb_streams; i++)
                if (rtp_hinting_needed(s->streams[i]))
                    nb_tracks++;
        }
        if (mov->nb_meta_tmcd)
            tmcd_track = nb_tracks;
    
        for (i = 0; i < s->nb_streams; i++) {
            int j;
            AVStream *st= s->streams[i];
            MOVTrack *track= &mov->tracks[i];
    
            // 如果存在extradata就进行拷贝
            if (st->codecpar->extradata_size) {
                if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
                    mov_create_dvd_sub_decoder_specific_info(track, st);
                else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
                    track->vos_len  = st->codecpar->extradata_size;
                    track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
                    if (!track->vos_data) {
                        return AVERROR(ENOMEM);
                    }
                    memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
                    memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
                }
            }
    
            if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
                track->par->channel_layout != AV_CH_LAYOUT_MONO)
                continue;
    
            for (j = 0; j < s->nb_streams; j++) {
                AVStream *stj= s->streams[j];
                MOVTrack *trackj= &mov->tracks[j];
                if (j == i)
                    continue;
    
                if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
                    trackj->par->channel_layout != AV_CH_LAYOUT_MONO ||
                    trackj->language != track->language ||
                    trackj->tag != track->tag)
                    continue;
                track->multichannel_as_mono++;
            }
        }
    
        if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
            if ((ret = mov_write_identification(pb, s)) < 0)
                return ret;
        }
        if (mov->reserved_moov_size){
            mov->reserved_header_pos = avio_tell(pb);
            if (mov->reserved_moov_size > 0)
                avio_skip(pb, mov->reserved_moov_size);
        }
        if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
            // 设置flag为FF_MOV_FLAG_FRAG_KEYFRAME
            if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
                                FF_MOV_FLAG_FRAG_CUSTOM |
                                FF_MOV_FLAG_FRAG_EVERY_FRAME)) &&
                !mov->max_fragment_duration && !mov->max_fragment_size)
                mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
        } else {
            if (mov->flags & FF_MOV_FLAG_FASTSTART)
                mov->reserved_header_pos = avio_tell(pb);
    		// 写入mdat的tag
            mov_write_mdat_tag(pb, mov);
        }
    
        ff_parse_creation_time_metadata(s, &mov->time, 1);
        if (mov->time)
            mov->time += 0x7C25B080; // 1970 based -> 1904 based
    
        if (mov->chapter_track)
            if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
                return ret;
    
        if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
            for (i = 0; i < s->nb_streams; i++) {
                if (rtp_hinting_needed(s->streams[i])) {
                    if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
                        return ret;
                    hint_track++;
                }
            }
        }
        if (mov->nb_meta_tmcd) {
            const AVDictionaryEntry *t, *global_tcr = av_dict_get(
    			s->metadata, "timecode", NULL, 0);
            // 初始化tmcd的track轨道
            for (i = 0; i < s->nb_streams; i++) {
                AVStream *st = s->streams[i];
                t = global_tcr;
    
                if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                    AVTimecode tc;
                    if (!t)
                        t = av_dict_get(st->metadata, "timecode", NULL, 0);
                    if (!t)
                        continue;
                    if (mov_check_timecode_track(s, &tc, i, t->value) < 0)
                        continue;
                    if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
                        return ret;
                    tmcd_track++;
                }
            }
        }
        avio_flush(pb);
        if (mov->flags & FF_MOV_FLAG_ISML)
            mov_write_isml_manifest(pb, mov, s);
        // 写入moov的tag
        if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
            !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
            if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
                return ret;
            mov->moov_written = 1;
            if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
                mov->reserved_header_pos = avio_tell(pb);
        }
    
        return 0;
    }

    总结一下,mov_write_header函数主要做4件事情:

    • 拷贝extradata;
    • 写入mdat的tag或设置fragment的flag;
    • 初始化tmcd(timecode)的track轨道;
    • 写入moov的tag;

    至此, avformat_write_header()写文件头的函数分析完毕。

    展开全文
  • MongoDB 批量操作(bulkWrite)

    千次阅读 2020-03-26 21:01:53
    mongodb 3.2 版中的新版本提供了db.collection.bulkWrite() 方法提供了执行批量插入、更新和删除操作的能力。 mongodb 还支持批量插入 db.collection.insertMany()。 1.1、语法 db.collection.bulkWrite( [ <...

    一、概述

    mongodb 3.2 版中的新版本提供了db.collection.bulkWrite() 方法提供了执行批量插入、更新和删除操作的能力。

    mongodb 还支持批量插入 db.collection.insertMany()。

    1.1、语法

    db.collection.bulkWrite(
       [ <operation 1>, <operation 2>, ... ],
       {
          writeConcern : <document>,
          ordered : <boolean>
       }
    )
    
    参数类型描述
    operationsarraybulkWrite() 写操作的数组。支持操作:insertOne、updateOne、updateMany、deleteOne、deleteMany、replaceOne
    writeConcerndocument可选, write concern 文档,省略则使用默认的 write concern。
    orderedboolean可选,表示mongod实例有序还是无序执行操作。默认值true。

    方法返回值:

    • 操作基于 write concern 运行则 acknowledged 值为true,如果禁用 write concern 运行则 acknowledged 值为false。
    • 每一个写操作数。
    • 成功 inserted 或 upserted文档的 _id 的组数。

    行为

    bulkWrite() 接收一个写操作的数组然后执行它们中的每一个。默认是有序的执行。

    二、写操作

    insertOne

    插入单个文档到集合中。

    db.collection.bulkWrite( [
       { insertOne : { "document" : <document> } }
    ] )
    

    updateOne 及 updateMany

    updateOne 更新集合中 filter 匹配的单个文档。如果匹配到多个文档 updateOne 仅更新第一个匹配到的文档。

    db.collection.bulkWrite( [
       { updateOne :
          {
             "filter" : <document>,
             "update" : <document>,
             "upsert" : <boolean>
          }
       }
    ] )
    

    updateMany 更新集合中所有匹配到的文档。

    db.collection.bulkWrite( [
       { updateMany :
          {
             "filter" : <document>,
             "update" : <document>,
             "upsert" : <boolean>
          }
       }
    ] )
    

    对字段的更新操作例如 $ set 、$ unset 、$rename等。

    默认情况 upsert 为 false。

    replaceOne

    replaceOne 替换集合中 filter 匹配到的单个文档。如果匹配到多个文档 replaceOne 只会替换一个匹配到的文档。

    db.collection.bulkWrite([
       { replaceOne :
          {
             "filter" : <document>,
             "replacement" : <document>,
             "upsert" : <boolean>
          }
       }
    ] )
    

    replacement 字段中不能包含 update 操作。

    默认情况 upsert 为 false。

    deleteOne 及 deleteMany

    deleteOne 删除集合中 filter 匹配到的单个文档。如果匹配到多个文档 deleteOne 只会删除一个匹配到的文档。

    db.collection.bulkWrite([
       { deleteOne :  { "filter" : <document> } }
    ] )
    

    deleteMany 删除集合中 filter 匹配到的所有文档。

    db.collection.bulkWrite([
       { deleteMany :  { "filter" : <document> } }
    ] )
    

    三、_id 字段

    如果文档未指定 _id 字段,则mongod会在 insert 或 upsert 文档之前添加 _id 字段并指定唯一的ObjectId。 大多数驱动程序会创建一个ObjectId并插入到 _id 字段,但如果驱动程序或应用程序没有,mongod将创建并填充 _id。

    如果文档包含 _id 字段,则 _id 值在集合中必须是唯一的,以避免重复键错误。

    更新或替换操作不能指定与原始文档不同的 _id 值。

    四、执行操作

    ordered 参数指定 bulkWrite() 是否有序执行,默认情况下是有序执行。

    含有6个操作的 bulkWrite() 代码如下:

    db.collection.bulkWrite(
       [
          { insertOne : <document> },
          { updateOne : <document> },
          { updateMany : <document> },
          { replaceOne : <document> },
          { deleteOne : <document> },
          { deleteMany : <document> }
       ]
    )
    

    默认情况下 ordered : true ,每个操作将会有序的执行,从第一个insertOne 到最后一个deleteMany 顺序执行。

    应用程序不依赖操作执行顺序是,可以设置 ordered 为 false ,此时mongod 会重新排序操作来提高性能。

    含有6个操作无序的 bulkWrite() 代码如下:

    db.collection.bulkWrite(
       [
          { insertOne : <document> },
          { updateOne : <document> },
          { updateMany : <document> },
          { replaceOne : <document> },
          { deleteOne : <document> },
          { deleteMany : <document> }
       ],
       { ordered : false }
    )
    

    对于ordered:false,操作结果可能会有所不同。 例如,deleteOne或deleteMany 删除的文档可能会变多或变少,具体取决于deleteOne或deleteMany 是在insertOne,updateOne,updateMany或replaceOne操作之前或之后的运行。

    每组操作最多可以有1000次操作。 如果一个组超过此限制,MongoDB会将该组划分为1000或更小的组。 例如,如果队列包含2000个操作,MongoDB将创建2个组,每个组具有1000个操作。

    大小和分组机制是内部的执行细节,在将来的版本中可能会有所变化。

    在分片集合上执行有序操作通常比执行无序操作慢,因为对于有序,每个操作必须等待上一个操作完成。

    五、固定集合(Capped Collections)

    bulkWrite() 写操作在固定集合上使用有所限制。

    • updateOne 和 updateMany 更新时增加了被修改文档的大小将会抛出 WriteError

    • replaceOne 操作替换的文档比之前的文档大会抛出 WriteError

    • deleteOne 和 deleteMany 操作在固定集合上会抛出 WriteError

    六、操作处理(Error Handling)

    bulkWrite() 在错误发生时会抛出 BulkWriteError 异常。

    排除Write Concern错误,有序操作在发生错误后停止,及无序操作继续处理队列中的剩余写入操作。

    Write Concern 错误显示在 writeConcernErrors字段中,而所有其他错误都显示在writeErrors字段中。 如果遇到错误,则显示成功写入操作的数量而不是插入的_id值。 有序操作显示遇到的单个错误,而无序操作显示数组中的每个错误。

    七、实例

    7.1、批量写

    characters 集合包含以下文档:

    { "_id" : 1, "char" : "Brisbane", "class" : "monk", "lvl" : 4 },
    { "_id" : 2, "char" : "Eldon", "class" : "alchemist", "lvl" : 3 },
    { "_id" : 3, "char" : "Meldane", "class" : "ranger", "lvl" : 3 }
    

    bulkWrite() 在集合上执行批量操作:

    try {
       db.characters.bulkWrite(
          [
             { insertOne :
                {
                   "document" :
                   {
                      "_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
                   }
                }
             },
             { insertOne :
                {
                   "document" :
                   {
                      "_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
                   }
                }
             },
             { updateOne :
                {
                   "filter" : { "char" : "Eldon" },
                   "update" : { $set : { "status" : "Critical Injury" } }
                }
             },
             { deleteOne :
                { "filter" : { "char" : "Brisbane"} }
             },
             { replaceOne :
                {
                   "filter" : { "char" : "Meldane" },
                   "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
                }
             }
          ]
       );
    }
    catch (e) {
       print(e);
    }
    

    操作结果如下:

    {
       "acknowledged" : true,
       "deletedCount" : 1,
       "insertedCount" : 2,
       "matchedCount" : 2,
       "upsertedCount" : 0,
       "insertedIds" : {
          "0" : 4,
          "1" : 5
       },
       "upsertedIds" : {
     
       }
    }
    

    如果 第二个 insertOne 操作的 _id 是集合中已经存在的,则会抛出以下错误:

    BulkWriteError({
       "writeErrors" : [
          {
             "index" : 0,
             "code" : 11000,
             "errmsg" : "E11000 duplicate key error collection: guidebook.characters index: _id_ dup key: { : 4 }",
             "op" : {
                "_id" : 5,
                "char" : "Taeln"
             }
          }
       ],
       "writeConcernErrors" : [ ],
       "nInserted" : 1,
       "nUpserted" : 0,
       "nMatched" : 0,
       "nModified" : 0,
       "nRemoved" : 0,
       "upserted" : [ ]
    })
    

    默认情况下 ordered 为 true, 顺序执行时遇到错误就停止执行(后续的操作不会被执行)。

    7.2、无序批量写

    characters 集合包含以下文档:

    { "_id" : 1, "char" : "Brisbane", "class" : "monk", "lvl" : 4 },
    { "_id" : 2, "char" : "Eldon", "class" : "alchemist", "lvl" : 3 },
    { "_id" : 3, "char" : "Meldane", "class" : "ranger", "lvl" : 3 }
    

    bulkWrite() 在集合上执行批量操作:

    try {
       db.characters.bulkWrite(
             [
                { insertOne :
                   {
                      "document" :
                      {
                         "_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
                      }
                   }
                },
                { insertOne :
                   {
                      "document" :
                         {
                            "_id" : 4, "char" : "Taeln", "class" : "fighter", "lvl" : 3
                         }
                   }
                },
                { updateOne :
                   {
                      "filter" : { "char" : "Eldon" },
                      "update" : { $set : { "status" : "Critical Injury" } }
                   }
                },
                { deleteOne :
                   { "filter" : { "char" : "Brisbane"} }
                },
                { replaceOne :
                   {
                      "filter" : { "char" : "Meldane" },
                      "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
                   }
                }
             ],
                { ordered : false }
          );
       }
       catch (e) {
       print(e);
    }
    

    操作结果如下:

    BulkWriteError({
       "writeErrors" : [
          {
             "index" : 0,
             "code" : 11000,
             "errmsg" : "E11000 duplicate key error collection: guidebook.characters index: _id_ dup key: { : 4 }",
             "op" : {
                "_id" : 4,
                "char" : "Taeln"
             }
          }
       ],
       "writeConcernErrors" : [ ],
       "nInserted" : 1,
       "nUpserted" : 0,
       "nMatched" : 2,
       "nModified" : 2,
       "nRemoved" : 1,
       "upserted" : [ ]
    })
    

    无序操作,尽管操作过程中出现错误,剩余的操作也不会就此终止执行。

    7.3、基于 Write Concern 的批量写

    enemies 集合包含以下文档:

    { "_id" : 1, "char" : "goblin", "rating" : 1, "encounter" : 0.24 },
    { "_id" : 2, "char" : "hobgoblin", "rating" : 1.5, "encounter" : 0.30 },
    { "_id" : 3, "char" : "ogre", "rating" : 3, "encounter" : 0.2 },
    { "_id" : 4, "char" : "ogre berserker" , "rating" : 3.5, "encounter" : 0.12}
    

    以下使用 write concern 值为 “majority” 及 timeout 为 100 毫秒来执行批量写操作:

    try {
       db.enemies.bulkWrite(
          [
             { updateMany :
                {
                   "filter" : { "rating" : { $gte : 3} },
                   "update" : { $inc : { "encounter" : 0.1 } }
                },
     
             },
             { updateMany :
                {
                   "filter" : { "rating" : { $lt : 2} },
                   "update" : { $inc : { "encounter" : -0.25 } }
                },
             },
             { deleteMany : { "filter" : { "encounter" { $lt : 0 } } } },
             { insertOne :
                {
                   "document" :
                      {
                         "_id" :5, "char" : "ogrekin" , "rating" : 2, "encounter" : 0.31
                      }
                }
             }
          ],
          { writeConcern : { w : "majority", wtimeout : 100 } }
       );
    }
    catch (e) {
       print(e);
    }
    

    如果副本集中所有必需节点确认写入操作所需的总时间大于wtimeout,则在wtimeout 时间过去时将显示以下writeConcernError。

    BulkWriteError({
       "writeErrors" : [ ],
       "writeConcernErrors" : [
          {
             "code" : 64,
             "errInfo" : {
                "wtimeout" : true
             },
             "errmsg" : "waiting for replication timed out"
          }
       ],
       "nInserted" : 1,
       "nUpserted" : 0,
       "nMatched" : 4,
       "nModified" : 4,
       "nRemoved" : 1,
       "upserted" : [ ]
       })
    

    结果集显示执行的操作,因为writeConcernErrors错误不是任何写入操作失败的标志。

    展开全文
  • Datax 支持增量 oracle writeMode update

    千次阅读 热门讨论 2020-06-21 10:05:43
    columnHolders, List<String> valueHolders, String writeMode, DataBaseType dataBaseType, boolean forceUseUpdate) { boolean isWriteModeLegal = writeMode.trim().toLowerCase().startsWith("insert") || write...
  • Presto Cannot write to non-managed Hive table

    千次阅读 2022-03-23 11:06:58
    Cannot write to non-managed Hive table 网上搜了一下也没发现类似的错,不过让我注意到了non-managed Hive table。 那么,什么是non-managed Hive table? 查了一下才发现,原来 Managed Table 就是 Internal ...
  • 再探Linux内核write系统调用操作的原子性

    万次阅读 多人点赞 2017-12-23 13:52:52
    很多人都在问Linux系统的write调用到底是不是原子的。网上能搜出一大堆文章,基本上要么是翻译一些文献,要么就是胡扯,本文中我来结合实例来试着做一个稍微好一点的回答。  先摆出结论吧。结论包含两点,即write...
  • document write( )解析

    千次阅读 2019-04-25 16:31:21
    document write( )解析 转至:https://www.cnblogs.com/ziyunfei/p/5881426.html 该文主要作为学习笔记进行转载,如有侵权请联系 在传统的浏览器中,同步的 script 标签是会阻塞 HTML 解析器的,无论是内联的还是...
  • 小白一枚,开发项目过程中测试了下导出文件功能,发现了一个bug,控制台输出报错信息,结果是正确的,但是bug报在控制台真的不好看啊。弄了一天半,一路debug删删减减到service方法都注释掉了,...write javaBean
  • iwrite复制粘贴方法

    千次阅读 2022-04-11 21:46:14
    iwrite复制粘贴方法
  • Copy On Write机制了解一下

    万次阅读 多人点赞 2019-05-15 17:29:50
    执行BGSAVE命令或者BGREWRITEAOF命令的过程中,Redis需要创建当前服务器进程的子进程,而大多数操作系统都采用写时复制(copy-on-write)来优化子进程的使用效率,所以在子进程存在期间,服务器会提高负载因子的阈值...
  • linux中write函数详解

    千次阅读 2022-03-08 09:46:37
    1、write函数 头文件#include <unistd.h> 三个参数 函数说明:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。 返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生...
  • fortran中write用法

    千次阅读 2021-05-23 00:51:07
    fortran中write用法 格式化输出的控制字符非常的丰富,但常用的并不多,一般说来:" I 、F、E、A、X "是最常使用的几个格式,最好把它们都记下来。 Iw[.m] 以w个字符的宽度来输出整数,至少输出m个数字。 如:write(*...
  • Java Writer write()方法

    千次阅读 2021-03-07 08:32:28
    Java Writer write()方法java.io.Writer.write(String str,int off,int len)写入字符串的一部分。1 语法public void write(String str,int off,int len)2 参数str:要写入的字符串。off:开始写入字符的偏移量。len...
  • write.csv()函数--R语言

    万次阅读 2021-04-12 22:50:35
    write.table prints its required argument x (after converting it to a data frame if it is not one nor a matrix) to a file or connection. 将X输出到文件或者链接 函数语法: write.table(x, file = "", ...
  • python write( )函数

    千次阅读 2021-01-12 08:26:38
    (交流学习群 467604262)在博客(python 本地数据获取 网址:http://blog.csdn.net/sxingming/article/details/51333663)中...write( )函数的参数是一个字符串,分以下2种情况:1》通过write()函数向文件中写入一行>...
  • 文章目录 概览 Cache-Aside 读操作 更新操作 1、缓存失效 2、缓存更新 Read-Through Write-Through Write-Behind 总结 参考 概览 缓存是一个有着更快的查询速度的存储技术,这里的更快是指比起从初始的数据源查询...
  • fatfs文件系统详解之f_write函数分析

    千次阅读 2020-05-31 18:36:43
    本篇分析f_write()函数,fatfs文件系统对应的不知道文件的读写,也对应了文件的其他的操作,也有文件夹的操作,函数分析确实是一个非常耗时耗精力的事情,此函数分析完之后,就结束函数分析。 分析假设 (1)假设一...
  • fortran write格式

    千次阅读 2020-07-17 23:14:31
    write(*,"(f10.1)",advance="no")A 格式化输出的控制字符非常的丰富,但常用的并不多,一般说来:" I 、F、E、A、X "是最常使用的几个格式,最好把它们都记下来。 Iw[.m]以w个字符的宽度来输出整数,至少输出m个...
  • write函数过程解析 __write_nocancel

    千次阅读 2017-07-26 11:08:19
    write函数过程解析 write函数作为用户向终端或者文件进行写数据的重要函数,有着重要的作用。 |------| |---------| |---------| |----------|  | write |----->|sys_write|-------->|vfs_write|------->|ext...
  • document中的write用法

    万次阅读 多人点赞 2018-08-28 20:07:02
    一、document.write()运行原理  首先我们先了解一下这条语句运行的原理:  document.write()是Javascript中对document.open()所开启的文档流操作的API方法。  它能够直接砸文档流中写入字符串,一旦文档流已经...
  • turtle.write方法使用说明

    万次阅读 多人点赞 2021-02-21 10:56:13
    turtle.write方法使用说明 关于turtle可参见 Python新手入门学习讲座系列文章 https://blog.csdn.net/cnds123/article/details/108676296 turtle.write()方法 在当前乌龟位置写入文本。使用格式: write(arg...
  • 在ARM开发板上跑如下测试程序的时候会概率性出现“Write Failed Bad address”: /* Write test */ #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #...
  • python中write方法是如何使用?

    千次阅读 2020-11-29 11:36:39
    关于这个函数,之前小编给大家介绍过,不知道大家还有印象吗,今天再把这个函数拿来跟...语法write(data)data为要写入的数据,可以为字符串str类型,也可以是bytes类型。二、 案例1、实现一个文本文件的拷贝,使用...
  • Android 10+ 适配数据存取权限,WRITE_EXTERNAL_STORAGE no longer provides write access when targeting Android 10+Android 10+ 适配数据存取权限简介方法总结 Android 10+ 适配数据存取权限 你好! 这是你第一次...
  • prometheus的remote write功能

    千次阅读 2020-08-30 17:37:54
    prometheus配置了remote write的目标地址后,它会从WAL读取数据,然后把采样数据写入各分片的内存队列,最后发起向远程目标地址的请求。 数据流的逻辑大致如下: |--> queue (shard_1) --> remote endpoint ...
  • Python中write()方法有哪些功能?

    千次阅读 2021-01-29 04:43:34
    摘要:下文讲述Python中write()的方法的功能简介说明,如下所示:write()方法功能:用于向文件中写入指定字符串(如:写入一个列表)write()方法语法fileObject.write(str)--------参数说明--------fileObject:文件对象...
  • 最近用libcurl开源库做了...1,curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpPostWriteBack); HttpPostWriteBack是回调函数指针,需要自己实现原型为:unsigned int HttpPostWriteBack(void *contents, siz...
  • python文件写入write()的操作

    千次阅读 2020-12-19 17:02:32
    本文实例为大家分享了python文件写入write()的操作的具体代码,供大家参考,具体内容如下filename = 'pragramming.txt'with open(filename,'w') as fileobject: #使用‘w'来提醒python用写入的方式打开fileobject....
  • 通过微信搜索公众号:iWrite爱写作,点击“关注”。一、注册iWrite英语写作教学与评阅系统移动端首页底端显示“登录”按钮。首次关注,点击“登录”按钮,页面跳转至登录/注册界面。点击“注册账号”按钮,即可跳转...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,160,057
精华内容 1,264,022
关键字:

write