首頁 資料庫 mysql教程 HDFS格式化过程分析

HDFS格式化过程分析

Jun 07, 2016 pm 04:34 PM
hdfs 分析 我們 格式化 知道 過程

我们知道,Namenode启动时可以指定不同的选项,当指定-format选项时,就是格式化Namenode,可以在Namenode类中看到格式化的方法,方法签名如下所示: private static boolean format(Configuration conf, boolean isConfirmationNeeded, boolean isInteracti

我们知道,Namenode启动时可以指定不同的选项,当指定-format选项时,就是格式化Namenode,可以在Namenode类中看到格式化的方法,方法签名如下所示:

private static boolean format(Configuration conf,
      boolean isConfirmationNeeded, boolean isInteractive) throws IOException
登入後複製

在该方法中,首先调用FSNamesystem类的方法,获取到待格式化的name目录和edit目录:

Collection editDirsToFormat = Collection dirsToFormat = FSNamesystem.getNamespaceDirs(conf);
FSNamesystem.getNamespaceEditsDirs(conf);
登入後複製

跟踪调用FSNamesystem类的方法,可以看到,实际上获取到的目录为:

  • name目录:是根据配置的dfs.name.dir属性,如果没有配置,默认使用目录/tmp/hadoop/dfs/name。
  • edit目录:是根据配置的dfs.name.edits.dir属性,如果没有配置,默认使用目录/tmp/hadoop/dfs/name。

在上面format方法中,创建对应的name目录和edit目录,对应如下代码行:

FSNamesystem nsys = new FSNamesystem(new FSImage(dirsToFormat, editDirsToFormat), conf);
登入後複製

实际上是调用FSImage对象的format方法格式化HDFS文件系统,调用代码如下所示:

    nsys.dir.fsImage.format();
登入後複製

下面,对上面提到的关键操作进行详细说明:

FSImage对象初始化

从上面用到的FSImage的构造方法,我们可以看到,在创建Namenode的目录对象时,主要是按照name和edit目录分别进行处理的:对于name目录,对应的存储目录类型可能是IMAGE或者IMAGE_AND_EDITS,当配置的name目录和edit目录相同时,类型为IMAGE_AND_EDITS,不同时类型为IMAGE;对于edit目录,类型就是EDITS。
name和edit目录实际上就是FSImage对象所包含的内容,这个FSImage对象包含一个StorageDirectory对象列表,而FSImage继承自抽象类org.apache.hadoop.hdfs.server.common.Storage,在该抽象类中定义如下所示:

  protected List storageDirs = new ArrayList();
登入後複製

这个列表中每个存储目录包含如下信息,如下Storage.StorageDirectory类图所示:
StorageDirectory
从类图中可以看到,主要包含如下三个信息:

  • root:配置的根目录路径
  • lock:一个FileLock文件锁对象,控制root下的写操作
  • dirType:表示StorageDirectory对象所使用目录的类型

一个dirType,它是Storage.StorageDirType类型的,Storage.StorageDirType是一个接口,定义如下所示:

  public interface StorageDirType {
    public StorageDirType getStorageDirType();
    public boolean isOfType(StorageDirType type);
  }
登入後複製

那么,对于Namenode节点的目录的Storage.StorageDirectory对象,它对应的dirType的定义,是实现了Storage.StorageDirType接口的枚举类,定义如下所示:FSImage.NameNodeDirType

  static enum NameNodeDirType implements StorageDirType {
    UNDEFINED,
    IMAGE,
    EDITS,
    IMAGE_AND_EDITS;
    public StorageDirType getStorageDirType() {
      return this;
    }
    public boolean isOfType(StorageDirType type) {
      if ((this == IMAGE_AND_EDITS) && (type == IMAGE || type == EDITS))
        return true;
      return this == type;
    }
  }
登入後複製

上述枚举类中定义的dirType恰好是前面我们提到的FSImage对象,所包含的实际Storage.StorageDirectory对象的类型,初始化FSImage对象时,就是确定了FSImage对象所包含的Storage.StorageDirectory对象列表及其它们的类型信息。

FSNamesystem对象初始化

FSNamesystem是个非常关键的类,它用来保存与Datanode相关的一些信息,如Block到Datanode的映射信息、StorageID到Datanode的映射信息等等。
前面调用的FSNamesystem的构造方法,如下所示:

  FSNamesystem(FSImage fsImage, Configuration conf) throws IOException {
    setConfigurationParameters(conf);
    this.dir = new FSDirectory(fsImage, this, conf);
    dtSecretManager = createDelegationTokenSecretManager(conf);
  }
登入後複製

初始化主要包括如下信息:

  1. 方法setConfigurationParameters根据传递的conf对象来设置FSNamesystem使用的一些参数值;
  2. 创建一个FSDirectory对象dir,该对象包含了一组用来维护Hadoop文件系统目录状态的操作,专门用来控制对目录的实际操作,如写操作、加载操作等,同时,它能够保持“文件->Block列表”的映射始终是最新的状态,并将变更记录到日志。
  3. 创建了一个DelegationTokenSecretManager对象,用来管理HDFS的安全访问。

在FSNamesystem中,创建的FSDirectory对象dir,是整个HDFS文件系统的根目录。对应的FSDirectory dir内部有一个inode表示,它是带配额的INodeDirectoryWithQuota rootDir,详细可见下面分析。

FSDirectory对象初始化

FSDirectory对象是很关键的,该类内部定义了如下字段:

  final FSNamesystem namesystem;
  final INodeDirectoryWithQuota rootDir;
  FSImage fsImage; 
  private boolean ready = false;
  private final int lsLimit;  // max list limit
  private final NameCache nameCache;
登入後複製

其中,rootDir表示一个带有配额限制的inode对象。下面我们看一下FSDirectory的构造方法:

  FSDirectory(FSImage fsImage, FSNamesystem ns, Configuration conf) {
    rootDir = new INodeDirectoryWithQuota(INodeDirectory.ROOT_NAME,
        ns.createFsOwnerPermissions(new FsPermission((short)0755)), Integer.MAX_VALUE, -1);
    this.fsImage = fsImage;
    fsImage.setRestoreRemovedDirs(conf.getBoolean(DFSConfigKeys.DFS_NAMENODE_NAME_DIR_RESTORE_KEY,
        DFSConfigKeys.DFS_NAMENODE_NAME_DIR_RESTORE_DEFAULT));
    fsImage.setEditsTolerationLength(conf.getInt(DFSConfigKeys.DFS_NAMENODE_EDITS_TOLERATION_LENGTH_KEY,
        DFSConfigKeys.DFS_NAMENODE_EDITS_TOLERATION_LENGTH_DEFAULT));
    namesystem = ns;
    int configuredLimit = conf.getInt(DFSConfigKeys.DFS_LIST_LIMIT, DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT);
    this.lsLimit = configuredLimit>0 ?
        configuredLimit : DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT;
    int threshold = conf.getInt(DFSConfigKeys.DFS_NAMENODE_NAME_CACHE_THRESHOLD_KEY,
        DFSConfigKeys.DFS_NAMENODE_NAME_CACHE_THRESHOLD_DEFAULT);
    NameNode.LOG.info("Caching file names occuring more than " + threshold + " times ");
    nameCache = new NameCache(threshold);
  }
登入後複製

这里创建了一个rootDir对象,如果我们调试跟踪该处代码,用户名为shirdrn,它的值可以表示如下:

"":shirdrn:supergroup:rwxr-xr-x
登入後複製

可见,对于FSNamesystem对象所维护的namespace中,inode对象包含目录名称、所属用户、所属用户组、操作权限信息。
上面构造方法中初始化了一个NameCache缓存对象,用来缓存经常用到的文件,这里提供了一个threshold值,默认为10。也就是如果当一个文件被访问的次数超过threshold指定的值,就会将该文件名称放进NameCache缓存中,实际上是该文件名称的字节码的ByteArray表示形式作为Key,它唯一表示了一个文件的inode节点。在NameCache内部,实际是将放到了其内部的HashMap集合中,Key是文件名称的ByteArray表示形式,Value封装了文件被访问的计数信息。

格式化HDFS

调用FSImage对象的format方法,该方法实现代码,如下所示:

  public void format() throws IOException {
    this.layoutVersion = FSConstants.LAYOUT_VERSION;
    this.namespaceID = newNamespaceID();
    this.cTime = 0L;
    this.checkpointTime = FSNamesystem.now();
    for (Iterator it = dirIterator(); it.hasNext();) {
      StorageDirectory sd = it.next();
      format(sd);
    }
  }
登入後複製

根据上面代码逻辑,详细说明如下:

  • layoutVersion

layoutVersion定义了HDFS持久化数据结构的版本号,它的值是负值。当HDFS的持久化数据结构发生了变化,如增加了一些其他的操作或者字段信息,则版本号会在原来的基础上减1。Hadoop 1.2.1版本中,layoutVersion的值是-41,它与Hadoop的发行版本号是两回事,如果layoutVersion的值变化了(通过减1变化,实际layoutVersion的值更小了),则如果能够读取原来旧版本的数据,必须执行一个升级(Upgrade)过程。layoutVersion主要在fsimage和edit日志文件、数据存储文件中使用。

  • namespaceID

namespaceID唯一标识了HDFS,在格式化HDFS的时候指定了它的值。在HDFS集群启动以后,使用namespaceID来识别集群中的Datanode节点,也就是说,在HDFS集群启动的时候,各个Datanode会自动向Namenode注册获取到namespaceID的值,然后在该值存储在Datanode节点的VERSION文件中。

  • cTime

cTime表示Namenode存储对象(即FSImage对象)创建的时间,但是在初始化时它的值为0。如果由于layoutVersion发生变化触发了一次升级过程,则会更新该事件字段的值。

  • checkpointTime

checkpointTime用来控制检查点(Checkpoint)的执行,为了在集群中获取到同步的时间,使用通过调用FSNamesystem对象的的now方法来生成时间戳。Hadoop使用检查点技术来实现Namenode存储数据的可靠性,如果因为Namenode节点宕机而无法恢复数据,则整个集群将无法工作。

  • 格式化StorageDirectory对象

我们知道,每一个Storage对象都包含一个StorageDirectory列表,FSImage就是Namenode用来存储数据的对象的实现,上面代码中通过for循环分别格式化每一个StorageDirectory对象,对应的format方法代码,如下所示:

  void format(StorageDirectory sd) throws IOException {
    sd.clearDirectory(); // create currrent dir
    sd.lock();
    try {
      saveCurrent(sd);
    } finally {
      sd.unlock();
    }
    LOG.info("Storage directory " + sd.getRoot() + " has been successfully formatted.");
  }
登入後複製

上面调用sd.lock()会创建一个${dfs.name.dir}/in_use.lock锁文件,用来保证当前只有同一个进程能够执行格式化操作。格式化的关键逻辑,都在saveCurrent方法中,代码如下所示:

  protected void saveCurrent(StorageDirectory sd) throws IOException {
    File curDir = sd.getCurrentDir();
    NameNodeDirType dirType = (NameNodeDirType)sd.getStorageDirType();
    // save new image or new edits
    if (!curDir.exists() && !curDir.mkdir())
      throw new IOException("Cannot create directory " + curDir);
    if (dirType.isOfType(NameNodeDirType.IMAGE))
      saveFSImage(getImageFile(sd, NameNodeFile.IMAGE));
    if (dirType.isOfType(NameNodeDirType.EDITS))
      editLog.createEditLogFile(getImageFile(sd, NameNodeFile.EDITS));
    // write version and time files
    sd.write();
  }
登入後複製

每一个StorageDirectory对象代表一个存储目录的抽象,包含root、lock、和dirType三个属性,在格式化过程中,如果已经存在则要首先删除,然后创建对应的目录。该目录实际的绝对路径为:

${dfs.name.dir}/current/
登入後複製

指定了根目录,就要创建对应的文件,这里面会生成文件fsimage、edits两个重要的文件,我们分别详细说明这两个文件中保存的内容:

  • 初始化fsimage文件数据

对应代码行如下:

    if (dirType.isOfType(NameNodeDirType.IMAGE))
      saveFSImage(getImageFile(sd, NameNodeFile.IMAGE));
登入後複製

如果StorageDirectory对象的dirType为IMAGE,则会在上面的current目录下创建一个文件:

${dfs.name.dir}/current/fsimage
登入後複製

可以通过saveFSImage方法看到,主要执行的操作,将数据存储到fsimage文件中,代码如下所示:

    try {
      out.writeInt(FSConstants.LAYOUT_VERSION);
      out.writeInt(namespaceID);
      out.writeLong(fsDir.rootDir.numItemsInTree());
      out.writeLong(fsNamesys.getGenerationStamp());
      byte[] byteStore = new byte[4*FSConstants.MAX_PATH_LENGTH];
      ByteBuffer strbuf = ByteBuffer.wrap(byteStore);
      // save the root
      saveINode2Image(strbuf, fsDir.rootDir, out);
      // save the rest of the nodes
      saveImage(strbuf, 0, fsDir.rootDir, out);
      fsNamesys.saveFilesUnderConstruction(out);
      fsNamesys.saveSecretManagerState(out);
      strbuf = null;
    } finally {
      out.close();
    }
登入後複製

首先,保存了文件系统的一些基本信息,如下表所示:

序号 字段 类型 说明
1 layoutVersion int -47,Hadoop-1.2.1对应的layoutVersion=-41
2 namespaceID int 标识HDFS的namespaceID
3 numItemsInTree long 1,当前只有文件系统root目录,对应于nsCount的值(Namespace Count)
4 generationStamp long FSNamesystem文件系统生成的时间戳

其次,调用saveINode2Image方法中,保存了文件系统的root目录名称、长度,以及inode信息,如下表所示:

序号 字段 类型 说明
1 nameLen short 0,文件系统的root目录名为””,长度为0
2 name byte[] 文件系统的root目录名的字节数组,实际上一个空字节数组
3 replication short 0
4 modificationTime long root目录inode修改时间
5 accessTime long 0
6 preferredBlockSize long 0
7 blocks int -1
8 nsQuota long 2147483647,即Integer.MAX_VALUE
9 dsQuota long -1
10 username String 用户名
11 groupname String 用户组名
12 permission short 493,可以跟踪代码计算得到

然后,调用saveImage方法,保存了从root目录开始的剩余其他目录节点的信息。saveImage方法是一个递归方法,它能够根据给定的root目录来保存该目录下所有目录或文件的信息。我们知道,到目前为止,只是创建一个文件系统的root目录,并没有对应的孩子inode节点,所以这一步实际上没有存储任何inode信息。
接着,fsNamesys.saveFilesUnderConstruction(out)保存root目录的租约信息(Lease),代码如下所示:

  void saveFilesUnderConstruction(DataOutputStream out) throws IOException {
    synchronized (leaseManager) {
      out.writeInt(leaseManager.countPath()); // write the size
      for (Lease lease : leaseManager.getSortedLeases()) {
        for(String path : lease.getPaths()) {
          // verify that path exists in namespace
          INode node = dir.getFileINode(path);
          if (node == null) {
            throw new IOException("saveLeases found path " + path + " but no matching entry in namespace.");
          }
          if (!node.isUnderConstruction()) {
            throw new IOException("saveLeases found path " + path + " but is not under construction.");
          }
          INodeFileUnderConstruction cons = (INodeFileUnderConstruction) node;
          FSImage.writeINodeUnderConstruction(out, cons, path);
        }
      }
    }
  }
登入後複製

这里,leaseManager.countPath()的值为0,此时还没有任何文件的租约信息,所以for循环没有执行,此处只是写入了一个0值,表示leaseManager对象所管理的path的数量为0,如下表所示:

序号 字段 类型 说明
1 countPath int 0,leaseManager管理的path总数

调用fsNamesys.saveSecretManagerState(out)保存SecretManager的状态信息,跟踪代码可以看到在DelegationTokenSecretManager类中的saveSecretManagerState,如下所示:

  public synchronized void saveSecretManagerState(DataOutputStream out) throws IOException {
    out.writeInt(currentId);
    saveAllKeys(out);
    out.writeInt(delegationTokenSequenceNumber);
    saveCurrentTokens(out);
  }
登入後複製

顺序写入的字段数据,如下表所示:

序号 字段 类型 说明
1 currentId int 0
2 allKeySize int 0,所有的DelegationKey数量。(如不为0,后面会序列化每个DelegationKey对象)
3 delegationTokenSequenceNumber int 0
4 currentTokens int 0,所有DelegationTokenInformation数量。(如不为0,后面会序列化每个)DelegationTokenInformation对象)

上面的内容,都是fsimage文件保存的数据内容。

  • 初始化edits文件数据

对应代码行如下所示:

    if (dirType.isOfType(NameNodeDirType.EDITS))
      editLog.createEditLogFile(getImageFile(sd, NameNodeFile.EDITS));
登入後複製

首先获取到edits文件名称,亦即文件:

${dfs.name.dir}/current/edits
登入後複製

然后调用editLog对象的createEditLogFile方法真正创建该文件,方法实现如下所示:

  public synchronized void createEditLogFile(File name) throws IOException {
    EditLogOutputStream eStream = new EditLogFileOutputStream(name);
    eStream.create();
    eStream.close();
  }
登入後複製

创建了一个流对象EditLogOutputStream eStream,并初始化一些基本信息以用来操作edits文件,通过create方法可以很清楚地看到,如下所示:

    @Override
    void create() throws IOException {
      fc.truncate(0);
      fc.position(0);
      bufCurrent.writeInt(FSConstants.LAYOUT_VERSION);
      setReadyToFlush();
      flush();
    }
登入後複製

序列化写入了layoutVersion的值,这里是-41。
在EditLogOutputStream内部维护了2个buffer,一个是bufCurrent,另一个是bufReady,当有数据要写入时首先写入bufCurrent,然后将bufCurrent与bufReady交换,这时bufCurrent空闲了,可以继续写入新的数据,而bufReady中的数据会在调用flush()方法时被持久化写入到edits文件中。其中,上面的setReadyToFlush()方法就是用来交换2个buffer的。flush()方法调用了FSEditLog类的flushAndSync()方法最终写入到文件中,可以简单看一下对应的代码实现:

    @Override
    protected void flushAndSync() throws IOException {
      preallocate();            // preallocate file if necessary
      bufReady.writeTo(fp);     // write data to file
      bufReady.reset();         // erase all data in the buffer
      fc.force(false);          // metadata updates not needed because of preallocation
    }
登入後複製

这样,edits文件已经完成初始化。

  • 初始化VERSION文件数据

上面sd.write()完成了VERSION文件的初始化,实现代码在Storage.StorageDirectory.write()方法中,代码如下所示:

    public void write() throws IOException {
      corruptPreUpgradeStorage(root);
      write(getVersionFile());
    }
登入後複製

调用corruptPreUpgradeStorage方法检查是否是HDFS需要升级,如果需要升级,格式化过程失败(此时如果遗留的image目录存在),方法的实现如下所示:

  protected void corruptPreUpgradeStorage(File rootDir) throws IOException {
    File oldImageDir = new File(rootDir, "image");
    if (!oldImageDir.exists())
      if (!oldImageDir.mkdir())
        throw new IOException("Cannot create directory " + oldImageDir);
    File oldImage = new File(oldImageDir, "fsimage");
    if (!oldImage.exists())
      // recreate old image file to let pre-upgrade versions fail
      if (!oldImage.createNewFile())
        throw new IOException("Cannot create file " + oldImage);
    RandomAccessFile oldFile = new RandomAccessFile(oldImage, "rws");
    // write new version into old image file
    try {
      writeCorruptedData(oldFile);
    } finally {
      oldFile.close();
    }
  }
登入後複製

首先,如果在${dfs.name.dir}下面不存在image目录,则创建该目录,然后在image目录下面创建文件fsimage,写入该文件的数据内容,如下表所示:

序号 字段 类型 说明
1 layoutVersion int -47,Hadoop-1.2.1对应的layoutVersion=-41
2 “”.length() short 0,写入一个空字符””的长度,即0
3 “” char 空字符,显然,实际并没有写入该值
4 messageForPreUpgradeVersion String 写入如下预升级提示消息:“\nThis file is INTENTIONALLY CORRUPTED so that versions\nof Hadoop prior to 0.13 (which are incompatible\nwith this directory layout) will fail to start.\n”。

如果执行corruptPreUpgradeStorage方法没有抛出异常,则这时开始初始化VERSION文件,该文件路径为${dfs.name.dir}/current/VERSION,调用write(getVersionFile())来实现,主要是通过一个Properties props对象,将对应的属性信息写入VERSION文件,可以通过setFields方法看到:

  protected void setFields(Properties props, StorageDirectory sd) throws IOException {
    super.setFields(props, sd);
    boolean uState = getDistributedUpgradeState();
    int uVersion = getDistributedUpgradeVersion();
    if(uState && uVersion != getLayoutVersion()) {
      props.setProperty("distributedUpgradeState", Boolean.toString(uState));
      props.setProperty("distributedUpgradeVersion", Integer.toString(uVersion));
    }
    writeCheckpointTime(sd);
  }
登入後複製

调用基类的super.setFields(props, sd);方法,实现如下所示:

  protected void setFields(Properties props, StorageDirectory sd) throws IOException {
    props.setProperty("layoutVersion", String.valueOf(layoutVersion));
    props.setProperty("storageType", storageType.toString());
    props.setProperty("namespaceID", String.valueOf(namespaceID));
    props.setProperty("cTime", String.valueOf(cTime));
  }
登入後複製

综合上面分析,可以看到,对应写入到VERSION文件的内容如下所示:

序号 字段 类型 说明
1 layoutVersion String -47,Hadoop-1.2.1对应的layoutVersion=-41
2 storageType String NAME_NODE
3 namespaceID String 对应的namespaceID值
4 cTime String 0,初始化为0

上面代码中uState=false,uVersion=0,getLayoutVersion()=-41,所以属性distributedUpgradeState和distributedUpgradeVersion没有添加到Properties中,例如,properties中的属性数据类似如下内容:
{namespaceID=64614865, cTime=0, storageType=NAME_NODE, layoutVersion=-41}
数据并没直接写入VERSION,而是等到初始化fstime文件完成之后,延迟初始化VERSION文件,以及,写入fstime文件先于写入VERSION文件。

  • 初始化fstime文件数据

在初始化VERSION文件时,调用了writeCheckpointTime(sd)方法,写入checkpointTime到文件${dfs.name.dir}/current/fstime中,代码如下所示:

  void writeCheckpointTime(StorageDirectory sd) throws IOException {
    if (checkpointTime 
<p>实际上写入fstime文件的只是检查点的时间,如下表所示:</p>
登入後複製
序号 字段 类型 说明
1 checkpointTime long 检查点时间戳,例如:1398180263639

格式化实例分析

下面,我们通过配置Hadoop-1.2.1,并执行HDFS的格式化操作,观察对应的目录的结构和数据。
首先配置Hadoop,各个配置文件如下所示:

配置项 配置值 配置文件
fs.default.name hdfs://localhost:9000 core-site.xml
dfs.replication 1 hdfs-site.xml
dfs.name.dir /home/shirdrn/programs/hadoop/dfs/name hdfs-site.xml
dfs.data.dir /home/shirdrn/programs/hadoop/dfs/data hdfs-site.xml

格式化后,在/home/shirdrn/programs/hadoop/dfs/name/current目录下生成如下4个文件:

edits
fsimage
fstime
VERSION
登入後複製

上面4个文件中,VERSION文件实际上是一个properties文件,它的内容是可读的字符串信息,内容如下所示:

#Thu Apr 10 21:49:18 PDT 2014
namespaceID=1858400315
cTime=0
storageType=NAME_NODE
layoutVersion=-41
登入後複製

第一次进行格式化,cTime=0。
对于其它几个文件,使用了Java的序列化方式进行存储,不是字符串可读格式的,可以参考源代码中实际序列化写入的内容,见上面给出的表格中列出的字段信息。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

dos指令怎麼格式化c盤 dos指令怎麼格式化c盤 Feb 19, 2024 pm 04:23 PM

DOS命令是Windows作業系統中使用的命令列工具,它可以用來執行各種系統管理任務和操作。其中一個常用的任務是格式化硬碟,包括C碟。格式化C碟是一個比較危險的操作,因為它將會清除C碟上的所有數據,並將檔案系統重新初始化。在執行這個操作之前,請確保你已經備份了重要的文件,並且清楚地了解格式化操作對你的電腦會產生的影響。下面是在DOS命令列中格式化

手機格式化恢復方法大揭密(手機故障?別急) 手機格式化恢復方法大揭密(手機故障?別急) May 04, 2024 pm 06:01 PM

現今,無法開機等,卡頓,我們難免會遇到一些問題,例如係統崩潰、但在使用過程中、手機已成為我們生活中不可或缺的一部分。我們往往束手無策、有時、對於這些問題的解決方法。幫助你解決手機故障,本文將為大家介紹一些手機格式化恢復的方法、讓手機重新恢復正常運作。備份資料-保護重要資訊安全通訊錄等,如照片、聯絡人、以免在格式化過程中遺失、在進行手機格式化之前、首先要考慮的是備份手機上的重要資料和檔案。確保資料的安全性、或選擇將檔案傳輸至雲端儲存服務中,可以透過連接電腦進行備份。使用系統自備恢復功能-簡

格式化筆記型電腦會使其速度更快嗎? 格式化筆記型電腦會使其速度更快嗎? Feb 12, 2024 pm 11:54 PM

格式化筆記型電腦會使其速度更快嗎?如果您想格式化您的Windows筆記型電腦,但想知道它是否會使速度更快,本文將幫助您了解這個問題的正確答案。格式化筆記型電腦會使其速度更快嗎?使用者格式化Windows筆記型電腦的原因有很多。但最常見的原因是筆記型電腦的效能或速度緩慢。格式化筆記型電腦會徹底刪除C碟或安裝Windows作業系統的硬碟分割區上儲存的所有資料。因此,每個用戶在採取這一步驟之前都會三思而後行,尤其是在筆記型電腦的性能方面。本文將幫助您了解格式化筆記型電腦是否會加快速度。格式化筆記型電腦有助於

電腦格式化教程 電腦格式化教程 Jan 08, 2024 am 08:21 AM

在使用電腦的時候很多時候都會遇到垃圾過多的情況,但是很多的用戶還不知道電腦怎麼格式化,沒關係,下面就給你們大家帶來了電腦格式化的教程一起看看吧。電腦怎麼格式化:1、右鍵點選桌面的「此電腦」點選「管理」。 2.在「電腦管理」中點選「儲存」開啟「磁碟管理」。 3、選擇自己要清理的硬碟右鍵選擇「格式化」。 4、勾選「執行快速格式化」並點選「確定」即可開始格式化。

html格式化的方法有哪些 html格式化的方法有哪些 Mar 08, 2024 am 09:53 AM

html格式化方法:1、使用線上HTML格式化工具;2、使用程式碼編輯器自帶的HTML格式化快速鍵,如Visual Studio Code中的Shift + Alt + F;3、使用插件,如Sublime Text中的HTML/CSS/JS Prettify插件;4、使用命令列工具,如HTML Tidy;5、手動格式化,依照編碼規格和習慣手動格式化。

織夢CMS二級目錄打不開的原因分析 織夢CMS二級目錄打不開的原因分析 Mar 13, 2024 pm 06:24 PM

標題:解析織夢CMS二級目錄打不開的原因及解決方案織夢CMS(DedeCMS)是一款功能強大的開源內容管理系統,被廣泛應用於各類網站建設中。然而,有時在搭建網站過程中可能會遇到二級目錄無法開啟的情況,這給網站的正常運作帶來了困擾。在本文中,我們將分析二級目錄打不開的可能原因,並提供具體的程式碼範例來解決這個問題。一、可能的原因分析:偽靜態規則配置問題:在使用

分析騰訊主要的程式語言是否為Go 分析騰訊主要的程式語言是否為Go Mar 27, 2024 pm 04:21 PM

標題:騰訊主要的程式語言是否為Go:一項深入分析騰訊作為中國領先的科技公司,在程式語言的選擇上一直備受關注。近年來,有人認為騰訊主要採用Go作為主要的程式語言。本文將對騰訊主要的程式語言是否為Go進行深入分析,並給出具體的程式碼範例來支持這一觀點。一、Go語言在騰訊的應用Go是一種由Google開發的開源程式語言,它的高效性、並發性和簡潔性受到眾多開發者的喜

Eclipse中的格式化快速鍵是什麼?全面解析! Eclipse中的格式化快速鍵是什麼?全面解析! Jan 03, 2024 pm 02:41 PM

Eclipse是一款廣泛應用於Java開發的整合開發環境(IDE)。它提供了許多功能和工具,使開發人員能夠更有效率地編寫和調試程式碼。其中一個非常重要且常用的功能是程式碼格式化,它能夠幫助開發人員統一程式碼風格,提高程式碼的可讀性和維護性。在Eclipse中,我們可以使用快捷鍵來快速進行程式碼格式化。本文將介紹Eclipse中常用的程式碼格式化快捷鍵,並對其進行詳細解析

See all articles