【Linux】文件
Linux 文件
- 什么叫文件
- C语言视角下文件的操作
- 文件的打开与关闭
- 文件的写操作
- 文件的读操作 & cat命令模拟实现
- 文件操作的系统接口
- open & close
- write
- read
- 文件描述符
- 进程与文件的关系
- 重定向问题
- Linux下一切皆文件的认识
- 文件缓冲区
- 缓冲区的刷新策略
- stuout & stderr
什么叫文件
狭义的文件:普通的磁盘文件
广义的文件:几乎所有的外设,都可以称作文件
站在系统的角度,那些能够被读取(input),或者能够被写出(output)的设备就叫做文件。
C语言视角下文件的操作
文件的打开与关闭
path
是文件的路径,mode
的选择如下。
// 此时是打开(或创建)当前路径下的文件 log.txt
FILE* pf = fopen("log.txt", "w");
所谓当前路径,准确来说是:当一个进程运行起来的时候,这个进程所处的工作路径。
以w
的方式打开,如果文件存在,会将文件清空(是在对文件读写操作之前);如果文件不存在,则会创建。
这里可以get到一个tips,就是如何将文件清空。
这里给出更直接的使用方法:> yourfile
。>
表示输入重定向。
以a
方式打开,是为了open for appending
,与其对应的有>>
追加重定向。
文件的关闭使用fclose
,传入文件指针就可以了。
文件的写操作
文件的写操作有多种,下面代码中给出部分示例。
const char* s[] = {"hello fwrite\n","hello fprintf\n","hello fputs\n"};fwrite(s[0], strlen(s[0]), 1, pf);
fprintf(pf, "%s", s[1]);
fputs(s[2], pf);
文件的读操作 & cat命令模拟实现
下面再以读的方式r
模拟实现cat
命令
读取信息的就用fgets
函数,
void Test1(int argc, char* argv[])
{if(argc != 2){printf("argv error!");exit(1);}FILE* pf = fopen(argv[1], "r");if(pf == NULL){perror("fopen");exit(2);}char line[64] = {0};while(fgets(line, sizeof(line), pf)){fprintf(stdout, "%s", line);}fclose(pf);
}
文件操作的系统接口
访问文件本质其实是进程通过调用接口访问,下面就来学习一下文件的调用接口。
open & close
open
的接口使用比较复杂。
如果想实现w
方式打开,需要如下的传参。
/*
* 宏定义,代表一个 bit 数据
* O_WRONLY 代表只写
* O_CREAT 代表创建文件
* O_TRUNC 代表清空文件
*/
int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC)
因为对于是否只写,是否创建,是否清空,这种非此即彼的选择很符合二进制位0与1的选择,open接口内部会对传输的flags
做位数据的判断来决定是否执行对应操作,这样可以简化接口的传参和节省空间。
上面O_*
的传参其实是宏定义,每一个这样的定义都对应一个bit位上的数据。
参数mode
是完成对文件权限属性的设置,用来设置文件权限的。
int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); // rw-rw-rw-
上面对文件权限的设置应该是-rw-rw-rw-
,可创建之后为什么是-rw-rw-r--
呢?
这和权限掩码umask
有关。
umask(0);
int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); // -rw-rw-rw-
将umask
设置0后,就看到了预期的-rw-rw-rw-
了。
文件关闭传入文件描述符(file descriptor)就行了。
对于文件描述符,open
函数创建文件成功就会返回这个文件的文件描述符,这里我们接收就好。
write
write
是用于文件写入的操作。
void Test2()
{int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0){perror("open");exit(1);}// 写操作const char* s = "hello world\n";write(fd, s, strlen(s));close(fd);
}
read
read
是用于文件的读取操作。
void test3()
{// O_RDONLY 只读int fd = open("./log.txt", O_RDONLY);if(fd < 0){perror("open");exit(1);}// 读操作char buffer[64] = {0};read(fd, buffer, sizeof(buffer));// 打印读取结果printf("%s", buffer);
}
文件描述符
上面对文件的操作都用到了一个东西,叫做文件描述符fd
,下面就来了解一下fd
是什么样一个东西吧。
void Test4()
{int fd1 = open("log1.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);assert(!(fd1 < 0));printf("open success, fd1: %d\n", fd1);int fd2 = open("log2.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);assert(!(fd1 < 0));printf("open success, fd2: %d\n", fd2);int fd3 = open("log3.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);assert(!(fd1 < 0));printf("open success, fd3: %d\n", fd3);int fd4 = open("log4.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);assert(!(fd1 < 0));printf("open success, fd4: %d\n", fd4);close(fd1);close(fd2);close(fd3);close(fd4);
}
为什么我们所创建的文件的文件描述符fd
是从 3 开始的呢?为什么不从 0 ,从 1 开始呢?
这是因为在运行C/C++程序是,会默认打开三个文件流:
stdin
标准输入;stdout
标准输出;stderr
标准错误。
这三个流的类型都是FILE*
的,FILE*
类型是结构体指针类型(FILE结构体是C标准库提供的),文件描述符fd
也只是这个结构体中的一个成员变量。而默认打开的这三个文件,它们已经占据了0,1,2三个fd
的值。
进程与文件的关系
文件大致可以分成两类:
- 磁盘文件(没有被打开,文件=内容+属性)
- 内存文件(进程在内存中打开)
进程要访问文件,必须先打开文件。一个进程可以打开多个文件(文件要被访问,必须是先加载到内存中)。
当多个进程都要访问文件时,系统中会存在大量的被打开的文件。
面对如此之多的被打开的文件,操作系统就要采用先描述,再组织的方式将这些被打开的文件进行管理。
Linux内核中,面对每一个被打开的文件都要构建一份struct file结构体(包含了一个被打开的文件的几乎所有的内容,不仅仅包含属性)
通过创建struct file对象来充当一个被打开的文件,并通过双链表的结构组织起来。
上面进程与文件的关系在内核代码中的体现如下图。
每个进程都有一个指针*files
, 指向一张表files_struct
,该表最重要的部分就是包含的一个指针数组,数组中每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件。
重定向问题
void Test5()
{ close(1); // fd的分配规则是:优先分配最小的,没有被占用的文件描述符 int fd = open("./log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);if(fd < 0) { perror("open"); exit(1);} // 应该往显示器(标准输出)上写入的// 但是都写入到了 log.txt// 这是什么呢?-> 输出重定向 printf("fd: %d\n", fd);fprintf(stdout, "hello fprintf\n");const char* s = "hello fwrite\n";fwrite(s,strlen(s), 1, stdout);fflush(stdout);close(fd);
}
代码中首先关闭了fd
为1的文件stdout
,体现在底层就是,文件描述符表中下标为1的元素不再指向标准输出流了。
这时立即创建了log.txt
文件,而fd
的分配规则是:优先分配最小的,没有被占用的文件描述符。于是给log.txt
分配文件描述符fd
是1。
然后再调用文件写入操作的一些接口向stdout
写入。默认是向fd
为1的文件进行写入。
这时就将本应显示到显示器上的内容写入到了log.txt
中。
同理,可以演示输入重定向的问题。
void Test6()
{ close(0); int fd = open("./log.txt", O_RDONLY); if(fd < 0) { perror("open"); exit(1); } printf("fd: %d\n", fd); // 输入重定向// 本来从键盘读取数据,变成从log.txt读取 char buffer[64] = {0}; fgets(buffer, sizeof buffer, stdin); // 将读取的信息进行打印printf("%s", buffer); close(fd);
}
从上面的式样中可以看出,重定向问题本质其实是在操作系统内部,更改fd
对应的内容的指向。
但是上面的重定向操作需要需要先手动关闭默认打开的文件流,这里介绍一个dup2
函数来更好的完成重定向操作。
dup2
接口中oldfd
和newfd
的拷贝不是单纯的int
的拷贝,反应在底层上是文件描述符所对应的数组元素中file*
指针的拷贝。
oldfd
拷贝给newfd
,最后newfd
所指向的内容是要和oldfd
一样的。
这里利用dup2
接口将>
重定向和>>
重定向的功能模拟实现一下。
void Test7()
{if(argc != 2){exit(1);}// 输入重定向int fd = open("./log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);// 追加重定向//int fd = open("./log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);if(fd < 0){perror("open");exit(2);}dup2(fd, 1);fprintf(stdout, "%s\n", argv[1]);close(fd);
}
Linux下一切皆文件的认识
LInux下一切皆文件,是体现在Linux操作系统的软件设计层面上的设计哲学。
当操作系统面对底层不同的硬件,一定对应的是不同的操作方法。
但是对于硬件这种设备都是外设,所以面对每一个设备的核心访问方法,都可以是 read/write
(I/O),但是基于不同的设备可以有自己不同的 read/write
,即在代码实现上是有差别的。
而且有些设备只能read
或者只能write
,对应实现的功能也会又所差异(比如键盘只能read
)。
但是操作系统将所有这些设备都看待成struct file
结构体,每一个设备都对应一个这样的struct file
,结构体里面包含了这些设备的属性和方法(方法其实是函数指针)。
当操作系统上层要调用哪个设备,就可以通过找到对应的struct file
,然后使用对应的操作方法使用设备了。
也就是说,在操作系统以上,就可以用一切皆文件的视角看待这些不同的设备了。
下面是内核代码中文件操作方法的函数指针。
文件缓冲区
缓冲区,简单说就是一段内存空间。它是由语言层提供的。它的存在可以提高整机效率,主要还是为了提高用户的响应速度(是一种写回模式)。
缓冲区的刷新策略
一般情况下有三种刷新策略:
- 立即刷新:写入缓冲区就立即刷新。
- 行刷新:写完一行内容再刷新。
- 满刷新:缓冲区写满再刷新。
特殊情况也会刷新:
- 用户强制刷新(fflush)。
- 进程退出。
其实,所有的设备,永远都倾向于全缓冲策略(缓冲区满了才刷新),这样做可以更少次地对外设进行访问,提高效率(和外部设备进行IO的时候,预备IO的过程是最费时间的)。
一般而言,行缓冲的设备文件有显示器,全缓冲的设备文件有磁盘文件。显示器的行刷新策略也是对效率和用户体验的折中处理。
void Test8()
{// C语言提供printf("hello printf\n");fprintf(stdout, "hello fprintf\n");const char* s1 = "hello fputs\n";fputs(s1, stdout);// OS提供const char* s2 = "hello write\n";write(1, s2, strlen(s2));// 调用fork时,上面的函数已经被执行完了,但并不代表数据已经刷新了fork();
}
Test8程序在执行向显示器打印时输出4行文本,向普通文件(磁盘上)打印却变成输出7行。这是为什么呢?
其实很明显是fork()
的原因,那fork()
又是如何作用出现这种情况呢?
细心观察发现,打印的内容中,系统接口的打印始终是一次,C语言接口相比会多打印一次。(从这里也可以猜到缓冲区是语言层提供的)
其实,如果是向显示器打印,刷新策略是行刷新,那么最后执行fork
的时候,之前的函数一定是执行完了,且数据已经被刷新了(行刷新)的,此时fork
就无意义了。
当程序重定向后,向磁盘文件打印,刷新策略隐形地变成了满刷新,此时fork
的时候,之前的函数一定是执行完了,但数据还没有刷新(在当前进程对应的C标准库中的缓冲区),这部分数据是属于父进程的数据的。而fork
之后,程序就要退出了,同时会强制将缓冲区的数据进行刷新。而父子进程的数据被刷新势必会影响到另一方,所以发生写时拷贝,父子进程各刷新一份数据到文件,就出现C接口的打印出现两份的情况了。
缓冲区是语言层提供的,封装的struct FILE
结构体内部就有所打开文件对应的语言层的缓冲区结构。
下面通过Test9可以对上面的解释做一个验证。
void Test9()
{// C语言提供printf("hello printf\n");fprintf(stdout, "hello fprintf\n");const char* s1 = "hello fputs\n";fputs(s1, stdout);// OS提供const char* s2 = "hello write\n";write(1, s2, strlen(s2));// fork之前,进行强制刷新fflush(stdout);// 调用fork时,上面的函数已经被执行完了,但并不代表数据已经刷新了fork();
}
stuout & stderr
stdout
对应的文件描述符是1,stderr
对应的文件描述符是2。
它们对应的都是显示器文件,但却是不同的。可以认为,同一个显示器文件,被打开了两次。
void Test10()
{// stdout -> 1printf("hello printf 1\n");fprintf(stdout, "hello fprintf 1\n");const char* s1 = "hello write 1\n";write(1, s1, strlen(s1));std::cout << "hello cout 1" << std::endl;// stderr -> 2 perror("hello perror 2");const char* s2 = "hello write 2\n";write(2, s2, strlen(s2));std::cerr << "hello cerr 2" << std::endl;
}
从这里发现,重定向的是1号文件描述符对应的文件。
所以可以通过重定向把标准输入和标准输出的内容输入到不同的文件中进行分开查看。
![在这里插入图片描述](https://img-blog.csdnimg.cn/e6143fe26eaa4f91b5604c946427517b.png =x150x)
一般而言,如果程序运行有,可能有错误的话,建议使用stderr
,或者cerr
来打印。如果是常规文本内容,建议使用cout
,stdout
打印。
当然也是可以将标准输入和标准输出的内容都输入到一个文件中的。
打印的内容中,有一个细节是perror
的打印包含有一段信息,其实就是错误码errno
对应的错误信息。
这里根据perror
的功能可以模拟实现一个进行理解。
void my_perror(const char* msg)
{ fprintf(stderr, "%s: %s\n", msg, strerror(errno));
}
相关文章:
【Linux】文件
Linux 文件 什么叫文件C语言视角下文件的操作文件的打开与关闭文件的写操作文件的读操作 & cat命令模拟实现 文件操作的系统接口open & closewriteread 文件描述符进程与文件的关系重定向问题Linux下一切皆文件的认识文件缓冲区缓冲区的刷新策略 stuout & stderr 什…...
Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img
我在 《Android 动态分区详解(二) 核心模块和相关工具介绍》 介绍过 lpmake 工具,这款工具用于将多个分区镜像打包生成一个 Android 专用的动态分区镜像,一般称为 super.img。Android 编译时,系统会自动调用 lpmake 并传入相关参数来生成 sup…...
信创环境 Phytium S2500 虚拟机最大内存规格测试
在 ARM 架构中,"IPA" 通常指的是 "Instruction Set Architecture"(指令集架构),arm环境的虚拟机支持的最大内存规格与母机上内存多少无关,由arm本身的ipa size决定,ipa size 可以理解为虚拟机的物理地址空间,kernel5.4.32中ipa默认是44bits(16T si…...
新建工程——第一个S32DS工程
之前的"测试开发板"章节 测试开发板——第一个AutoSAR程序,使用了一个 demo 工程,不管是裸机程序还是 AutoSAR 程序,那都是别人已经创建好的工程。本节来介绍如何来创建自己的工程,本节介绍如何创建一个 S32DS 的工程,点亮开发板上的 LED 我们从官方提供的例程…...
基于Open3D的点云处理16-特征点匹配
点云配准 将点云数据统一到一个世界坐标系的过程称之为点云配准或者点云拼接。(registration/align) 点云配准的过程其实就是找到同名点对;即找到在点云中处在真实世界同一位置的点。 常见的点云配准算法: ICP、Color ICP、Trimed-ICP 算法…...
设计模式—简单工厂
目录 一、前言 二、简单工厂模式 1、计算器例子 2、优化后版本 3、结合面向对象进行优化(封装) 3.1、Operation运算类 3.2、客户端 4、利用面向对象三大特性(继承和多态) 4.1、Operation类 4.2、加法类 4.3、减法类 4…...
真机安装Linux Centos7
准备工具: 8G左右U盘最新版UltraISOCentOS7光盘镜像 操作步骤 下载镜像 地址:http://isoredirect.centos.org/centos/7/isos/x86_64/ 安装刻录工具UltraISO,刻录镜像到U盘 ① 选择ISO镜像文件 ② 写入磁盘镜像,在这里选择你的U盘…...
ceph peering机制-状态机
本章介绍ceph中比较复杂的模块: Peering机制。该过程保障PG内各个副本之间数据的一致性,并实现PG的各种状态的维护和转换。本章首先介绍boost库的statechart状态机基本知识,Ceph使用它来管理PG的状态转换。其次介绍PG的创建过程以及相应的状…...
Java | File类
目录: File类File类中常用的方法:boolean exists( ) :判断此 文件/目录 是否存在boolean createNewFile( ) :创建一个文件boolean mkdir( ) :创建 “单层” 目录/文件夹boolean mkdirs( ) :创建 “多层” 目…...
数学建模之灰色预测
灰色预测(Grey Forecasting)是一种用于时间序列数据分析和预测的方法,通常用于处理具有较少历史数据的情况或者数据不够充分的情况。它是一种非常简单但有效的方法,基于灰色系统理论,用来估计未来的趋势。 以下是灰色…...
03_nodejd_npm install报错
npm install报错 npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: 5kcrm11.0.0 npm ERR! Found: vue2.5.17 npm ERR! node_modules/vue npm ERR! vue"2.5.17" from the root project npm ERR! np…...
three.js(二):webpack + three.js + ts
用webpackts 开发 three.js 项目 webpack 依旧是主流的模块打包工具;ts和three.js 是绝配,three.js本身就是用ts写的,ts可以为three 项目提前做好规则约束,使项目的开发更加顺畅。 1.创建一个目录,初始化 npm mkdir demo cd de…...
最小二乘法处理线性回归
最小二乘法是一种数学优化技术,用于查找最适合一组数据点的函数。 该方法主要用于线性回归分析,当然,也可用于非线性问题。 开始之前,我们先理解一下什么是回归。 回归:回归是一种监督学习算法,用于建模和…...
ModbusCRC16校验 示例代码
作者: Herman Ye Galbot Auromix 测试环境: Ubuntu20.04 更新日期: 2023/08/30 注1: Auromix 是一个机器人爱好者开源组织。 注2: 本文在更新日期经过测试,确认有效。 笔者出于学习交流目的, 给…...
一不留神就掉坑
乘除顺序问题 在据卡特兰数[1]公式,解决leetcode-96 不同的二叉搜索树[2]时,遇到一个非常诡异的问题, package mainimport "fmt"func main() { for i : 0; i < 40; i { fmt.Printf("第%d个卡特兰数为:%d\n", i, numTrees(i)) }}func numTrees(n int) i…...
Redis数据类型(list\set\zset)
"maybe its why" List类型 列表类型是⽤来存储多个有序的字符串,列表中的每个字符串称为元素(element),⼀个列表最多可以存储个2^32 - 1个元素。在Redis中,可以对列表两端插⼊(push)…...
TongWeb安装以及集成
TongWeb 安装步骤 静默安装 获取linux可执行安装包 如: Install_TWx.x.x.x_Enterprise_Linux.bin 创建安装所需配置文件 install.properties 内容如下 [root@node5 tongweb]# cat install.properties INSTALL_UI=silent USER_INSTALL_DIR=/home/tongweb SILENT_JDK_HOME=/jd…...
ScreenToGif-动图制作软件实用操作
ScreenToGif官网:ScreenToGif ⭕第一步:启动页面 ⭕第二步:选项 🥝录像机-捕获频率选择手动-播放延迟1000ms(可以任意) ⭕第三步:录像机开始录屏 🥝我们调整录屏的大小后,打开画图,…...
sqlibs安装及复现
sqlibs安装 安装phpstudy后,到github上获取sqlibs源码 sqli-labs项目地址—Github获取:GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based. 在phpstudy本地文件中的Apache目录中解压上方下载的源码。 将sq…...
OpenAI 创始人 Sam Altman 博客有一篇 10 年前的文章
OpenAI 创始人 Sam Altman 博客有一篇 10 年前的文章《Advice for ambitious 19 year olds》,给 19 岁年轻人的建议,从 #参考答案 看到,非常适合我们🤣年轻人,顺便用 GPT4 重新翻译了下全文。 太长不读纯摘要版本如下&…...
写的一款简易的热点词汇记录工具
项目需要对用户提交的附件、文章、搜索框内容等做热词分析。如下图: 公司有大数据团队。本着不麻烦别人就不麻烦别人的原则,写了一款简易的记录工具,原理也简单,手工在业务插入锚点,用分词器分好词,排掉字…...
算法通关村——滑动窗口高频问题
1. 无重复字符的最长子串 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 1.1 滑动窗口 找到最长字串需要找到字串的首尾位置…...
mybatis源码学习-2-项目结构
写在前面,这里会有很多借鉴的内容,有以下三个原因 本博客只是作为本人学习记录并用以分享,并不是专业的技术型博客笔者是位刚刚开始尝试阅读源码的人,对源码的阅读流程乃至整体架构并不熟悉,观看他人博客可以帮助我快速入门如果只是笔者自己观看,难免会有很多弄不懂乃至理解错误…...
selenium 自动化测试——环境搭建
安装python,并且使用pip命令安装 selenium pip3 install selenium 然后尝试第一次使用selenium 完成一个简单的测试自动化脚本 from selenium import webdriver from selenium.webdriver.common.by import By import timedriver webdriver.Chrome() driver.get(…...
得物一面,场景题问得有点多!
题目来源:https://www.nowcoder.com/discuss/525371909735792640 前文 本期是【捞捞面经】系列文章的第 1 期,持续更新中…。 《捞捞面经》系列正式开始连载啦,据说看了这个系列的朋友都拿到了大厂offer~ 欢迎星标订阅,持续更新…...
Prompt Tuning 和instruct tuning
Prompt Tuning 是啥? prompt的思想是,把下游任务的输入转化为预训练模型的原始任务。 以bert作为举例,假设任务是文本分类。“今天天气很好。”我们想判断一下这句话的情感是正面还是负面 fine-tune的方法是在bert之后接一个head࿰…...
springboot 与异步任务,定时任务,邮件任务
异步任务 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x之后&a…...
2022年06月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:小白鼠再排队2 N只小白鼠(1 < N < 100),每只鼠头上戴着一顶有颜色的帽子。现在称出每只白鼠的重量,要求按照白鼠重量从小到大的顺序输出它们头上帽子的颜色。帽子的颜色用 “red”,“blue”等字符串来表示。不同的小白鼠可…...
【C++】C++11新特性(下)
上篇文章(C11的新特性(上))我们讲述了C11中的部分重要特性。本篇接着上篇文章进行讲解。本篇文章主要进行讲解:完美转发、新类的功能、可变参数模板、lambda 表达式、包装器。希望本篇文章会对你有所帮助。 文章目录 一…...
python内网环境安装第三方包
文章目录 一、问题二、解决方法三、代码实现 一、问题 内网安装第三方包的应用场景,一般是一些需要在没网的环境下进行开发的情况。这些环境一般仅支持本地局域网访问,所以只能在不下载任何第三方包的情况下艰难开发。 二、解决方法 将当前应用依赖的第…...
如何申请网站域名/哪家网络公司比较好
tensorboard 作为一款可视化神器,可以说是学习tensorflow时模型训练以及参数可视化的法宝。 而在训练过程中,主要用到了tf.summary()的各类方法,能够保存训练过程以及参数分布图并在tensorboard显示。 tf.summary.scalar 用来显示标量信息…...
网站建设竞争对数分析/今日竞彩足球最新比赛结果查询
百度站长平台的链接提交工具主动推送功能升级了,这次升级最重要的是不会限制每天提交的链接数了! 以下是百度公告全文: 亲爱的网站管理员: 为配合Spider3.0系统的升级,百度站长平台的链接提交工具主动推送功能…...
毕业设计wordpress/seo基础课程
2017年高考已经圆满结束,出国留学网高考频道第一时间为大家提供2017自贡高考成绩查询系统已开通 ,更多高考分数线及高考志愿填报信息请关注我们网站的更新!点击下面图片即可进入四川省教育考试院查询2017年高考成绩:开通时间&…...
包装盒在线设计网站/青岛seo搜索优化
欢迎转载,但请务必在明确位置注明出处!http://stormzhang.com/android/2014/07/07/learn-android-from-rookie/QQ交流群:入群理由请正确填写我的GitHub账号 * 383323653 (Android学习之路1群,已满) * 187252236 (Android学习之路2…...
网站策划用培训吗/深圳网络推广引流
引言 50 多年前激光技术的发展催生了光探测和测距 (LIDAR) 系统,该系统在距离计算方式上取得了突破。LIDAR 的原理与雷达使用的原理非常相似。主要区别在于雷达系统检测物体反射的无线电波,而激光雷达使用激光信号。这两种技术通常采用相同类型的飞行时间…...
烟台优化公司/优化网站seo公司
众所周知,计算机底层的数据都是0和1. 那么我们在输入数字的时候,要交给计算机处理,首先要转化成计算机能识别的0和1的形式。那么文字是怎么样转化成0和1的呢? 通过字符集。常用的字符集是ASCII,每个字母每个符号都对应…...