• Linux 磁盘与文件系统管理


    Linux 磁盘与文件系统管理

    介绍一本书叫《Linux 鸟哥私房菜》, 一本教人用linux很经典的一本书,这两天又看了里面的一章节,做一点笔记。有一些很细节的东西的, 在平时运用过很容易被忽略。

    1)U盘使用的文件格式一般是FAT格式,这种格式的读写的方式,是读定完一个black后才知道下一个black的位置。所以当各个black很分散,要做磁盘碎片整理。

    2)Ext2是索引式文件系统,基本不太需要进行碎片整理。

    3)Ext2一个block的大小是一般4K

    4)block的大小与数量在格式化完就不能够再改变了,除了重新格式化。

    5)每个black内最多只能够旋转一个文件的数据。

    6)如果文件大于black的大小,则一个文件会占用多个black数据。
    7)若文件大小小于black,则该block剩余的空间就不能够再被使用了。

    8)日志文件系统 
        为了避免系统突然中断而导致文件数据不一致的情况发生,linux在 filesystem当中规划出一个区块,该区块专门在记录写入或修订档案时的步骤.如下: 
        1. 预备:当系统要写入一个档案时,会先在日志记录区块中纪录某个档案准备要写入的资讯; 
        2. 实际写入:开始写入档案的权限与资料;开始更新metadata的资料; 
        3. 结束:完成资料与metadata的更新后,在日志记录区块当中完成该档案的纪录 
        在这样的程序当中,万一资料的纪录过程当中发生了问题,那么我们的系统只要去检查日志记录区块,就 可以知道那个档案发生了问题,针对该问题来做一致性的检查即可,而不必针对整块filesystem去检查, 这样就可以达到快速修复filesystem的能力了!这就是日志式文件最基础的功能。

    9)Ext3是Ext2的升级版  具有 可利用性,数据完整性, 速度及转换的特点。
    10)目录
          1.当文件系统新建一个目录时,ext2会分配一个inode和至少一块block给这个目录。可以用 ls -i查看inode号码
          2.在一个目录下面如果文件过多,会导致一个block无法容纳,Linux会多给该目录block。
    11) 文件
          1.当文件系统新建一个文件时,ext2会分配一个Inode和相对该文件大小 的block数据给该文件。
          2.inode仅12个直接指向,其他是间接指向 双间接指向,三间接指向
     12)挂载点(mount point)
         1.将文件系统与目录结合的操作 称为挂载
         2.挂载点一定是目录,该目录为进入该文件系统的入口
         3.文件系统最顶层的目录的inode一般为2号
         4.单一文件系统不应该被重复挂载在不同的挂载点(目录)中
         5.单一目录不应该重复挂载多个文件系统
         6.作为挂载点的目录理论上应该都是空目录,如果有文件会被清空
     13)常见支持的文件系统
         1.传统文件系统:ext2/minix/MS-DOS/FAT(用vfs模块)/iso9660(光盘)等
         2.日志文件系统:ext3/ReiserFS/Windows'NTFS/IBM'sJFS/SGI'sXFS
         3.网路档案系统:NFS/SMBFS
         4.想知道Lininx支持文件有哪些,查看方法:ls -l /lib/modules/$(uname -r) /kernel/fs
         5.系统目前已加载到内存中支持的文件系统则有:cat /proc/filesystems
     14)Linux VFS 
         1.VFS  就是虚拟文件系统 (Virtual Filesysterm Switch)
         2. Linux 通过VFS管理所有它认识的文件系统
         3. 如图
                    
     

    15)硬连接

          由文件系统,我们可以得知:
          1.每个文件都会占用一个inode,文件内容由inode的记录来指向;
          2.想要读出文件,必须要经过目录记录的文件来指向正确的inode号码来读取。
         所谓的硬连接就是多个文件名对同一个inode。
         如图:
                 
          要注意两点:
          1.不能跨文件系统
          2.不能连接目录
     

    16) 符号连接

          1. 符号连接, 也称软连接,英文是 symbolic link
          2.符号连接在创建一个独立文件,而这个文件会让数据的读取指向它连接的那个文件的文件名。当源文件被删除时,符号连接会打不开。
          3.符号连接文件和源文件指向不同的inode。1的文件名指向了2的inode.由2的inode指向文件内容。
          4.原理如图:
     
                         
     
     
     
     
     
     
    分类: Linux

    Castle.DynamicProxy Part 1: ClassProxy

     

    1.Castle中代理对象的分类

    总的来说,代理对象大概可以分为2大类:

    1.继承类型的代理对象

    一类是继承类型的代理类。即:有一个类A,它的代理类是B。B是继承自A的。调用代理类B中的方法时,可以通过拦截器做一些逻辑判断等等。但注意,A中的类只能是virtual的才可以被代理。C#中只有virtual方法才能被override。

    这种代理类在castle的动态代理中只有一种,就是ClassProsy。也是最简单,最容易理解的一种代理类。

    2.组合类型的代理对象

    还有一类是组合型的代理类。即有一个类A,它的代理类是B。B不是继承自A的,而是B中包含了一个A的实例。这种代理就没有限制A中的方法必须是virtual的。

    这种代理类型在castle的动态代理中有如下几种:

    • class proxy with target
    • interface proxy without target
    • interface proxy with target
    • interface proxy with target interface

    这几种代理类将在后续的文章中进行分别说明。

    2.一个简单的classProxy例子

    准备一个汽车类,这个类在后面将会被代理

    创建一个简单的汽车类:为保持这个demo的简单,该类现在只有2个虚方法:Start和Stop。

    public class Car
        {public virtual void Start()
            {
                Console.WriteLine("启动");
            }
    
            public virtual void Stop()
            {
                Console.WriteLine("停止");
            }
        }

    创建一个拦截器

    创建一个简单的拦截器,这个拦截器只是很简单的在方法调用前和调用后打印一句话。

    public class SimpleInterceptor : Castle.Core.Interceptor.IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                Console.WriteLine("begin invoke");
                invocation.Proceed();
                Console.WriteLine("end invoke");
            }
        }

    创建Car类的一个代理

    使用ProxyGenerator的CreateClassProxy方法来创建一个代理。然后调用代理类的start和end方法。

    public class ClassProxyDemo
        {
            public void Main()
            {
                SimpleInterceptor interceptor = new SimpleInterceptor();
    
                //给Car类生成代理   
                ProxyGenerator generator = new ProxyGenerator();
                var car = generator.CreateClassProxy<Car>(new IInterceptor[]{interceptor});
                car.Start();
                car.Stop();
            }
        }

    可以想象一下,在调用start和end方法之前应该都会在控制台中打印出相应内容。以下是输出结果,和我们的预想一致。

    ------ Test started: Assembly: Castle.DynamicProxy.Demo.dll ------
    
    begin invoke
    启动
    end invoke
    begin invoke
    停止
    end invoke
    
    1 passed, 0 failed, 0 skipped, took 0.21 seconds (Ad hoc).
    
    

    将类的方法修改为非virtual

    如果将Car类的Stop方法改成非虚类,结果会是怎么样呢?

    public void Stop()
            {
                Console.WriteLine("停止");
            }

    输出的日志为:

    ------ Test started: Assembly: Castle.DynamicProxy.Demo.dll ------
    
    begin invoke
    启动
    end invoke
    停止
    
    1 passed, 0 failed, 0 skipped, took 0.21 seconds (Ad hoc).
    
    

    可以看到,只有start方法被拦截到了。stop方法没有没拦截到。

    在使用ClassProxy代理时,只有类的vierual方法,或者virtual属性才可以被代理。

    3.DynamicProxy中的拦截器

    首先看下Interceptor借口的定义吧:

    #region Assembly Castle.Core.dll, v1.1.0.0
    #endregion
    namespace Castle.Core.Interceptor
    {
        // Summary:
        //     New interface that is going to be used by DynamicProxy 2
        public interface IInterceptor
        {
            void Intercept(IInvocation invocation);
        }
    }
    

    IInvocation接口封装了对当前方法调用的所有信息。它的成员如下所示:

    dptutorial_1_iinvocation

    下面让我们来对拦截器做一些改进:

    改进1:获取拦截方法的名称

    我们希望拦截器中可以告诉我们当前是哪个方法被调用了,这个很简单,直接调用invocatiion.method的name属性即可。

    var metodInfo = invocation.Method;
         string methodName = metodInfo.Name;

    改进2:让拦截器有限速功能

    car是可以加速的,但是如果car的速度过高,我们就不允许加速了。为了实现这个功能,我们需要在car类中添加一个字段和属性来表述当前速度。

    private int _speed;
        public virtual int Speed { get { return _speed; } }

    在拦截器中进行判断,如果调用的是Accelerate方法,就判断,加速后的速度是否超速(>60)。如果不,允许加速。否则,不执行加速。

    public class SimpleInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                var metodInfo = invocation.Method;
                string methodName = metodInfo.Name;
    
                var car = invocation.InvocationTarget as Car;
                if(invocation.Arguments.Any())
                {
                    int speed = (int)invocation.Arguments[0];
                    
                    if (methodName == "Accelerate" && car.Speed + speed > 60)
                    {
                        Console.WriteLine("speed is too high...");
                        return;
                    }
                }
                
    invocation.Proceed();}
        }

    如果被代理类中的属性是virtual的,也可以被拦截。拦截的方法名是get_属性名。如访问代理类的Speed属性,被拦截的方法是:get_Speed。

    可以使用invocation.InvocationTarget as Car来访问代理类的实例。这样可以访问代理类中的属性等。在本例中是访问代理类的Speed属性。

    4.最终代码

    using System;
    using System.Linq;
    using Castle.Core.Interceptor;
    using Castle.DynamicProxy;
    
    
    namespace DotNetDemos.Castle.DynamicProxy2
    {
        public class ClassProxyDemo
        {
            public void Main()
            {
                SimpleInterceptor interceptor = new SimpleInterceptor();
    
                //给?Car类à生ú成é代ú理í   
                ProxyGenerator generator = new ProxyGenerator();
                var car = generator.CreateClassProxy<Car>(new IInterceptor[] { interceptor });
                //car.Start();
                //car.Stop();
                //car.Accelerate(40);
                //car.Accelerate(40);
                int speed= car.GetSpeed();
                Console.WriteLine(speed);
            }
        }
    
        public class SimpleInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                var metodInfo = invocation.Method;
                string methodName = metodInfo.Name;
    
                var car = invocation.InvocationTarget as Car;
                if(invocation.Arguments.Any())
                {
                    int speed = (int)invocation.Arguments[0];
                    
                    if (methodName == "Accelerate" && car.Speed + speed > 60)
                    {
                        Console.WriteLine("speed is too high...");
                        return;
                    }
                }
    
                Console.WriteLine("begin invoke {0} ",methodName);
                
                if (methodName == "GetSpeed")
                {
                    invocation.ReturnValue = 200;
                }
                else
                {
                    invocation.Proceed();
                }
                Console.WriteLine("end invoke {0} ",methodName);
            }
        }
    
        public class Car
        {
            private int _speed;
    
            public int Speed { get { return _speed; } }
    
            public virtual void Start()
            {
                Console.WriteLine("启动");
            }
    
            public virtual void Stop()
            {
                Console.WriteLine("停止");
            }
    
            public virtual void Accelerate(int speed)
            {
                _speed += speed;
                Console.WriteLine("加速: +{0}",speed);
            }
    
            public virtual void Decelerate(int speed)
            {
                _speed -= speed;
                Console.WriteLine("减速: -{0}",speed);
            }
    
            public virtual int GetSpeed()
            {
                return _speed;
            }
        }
    
    
    }

    5.总结

    本篇中介绍的ClassProxy是Castle的代理对象中唯一的一个继承类型的代理,这种代理要求被代理类的方法和属性必须是virtual的,侵入性比较强。和基于组合的代理对象相比,这种ClassProxy是相对比较简单的。接下来,会介绍Castel中的基于组合的代理对象,都是一些接口代理。功能更强大,在实际场景中也使用的更多。

    关于ClassProxy在实际项目中的使用场景,目前还不太清楚。。待研究。NHibernate的实体类映射时,实体的属性都要求是virtual的,应该是使用的ClassProxy。

     
     
     
  • 相关阅读:
    BackGroundWorker解决“线程间操作无效: 从不是创建控件的线程访问它”
    C#代码与javaScript函数的相互调用
    浅述WinForm多线程编程与Control.Invoke的应用
    web.config中appSettings配置节修改的函数
    迭代,递归的题目(转)
    一些计算机知识的总结(转)
    软件测试中条件覆盖,路径覆盖,语句覆盖,分支覆盖的区别
    在gridview的行绑定中应用AnimationExtender效果
    页头下拉广告,加了关闭按钮,不闪屏
    request.params
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3458855.html
Copyright © 2020-2023  润新知