• 日志 20071220(数组操作,File IO,using,TransactionScope)


    这两天写程序写的头昏脑涨,连日志几乎都没时间写了......

    1.昨晚在对一个Array做处理的时候,为了删除一个元素,写出了如代码段1非常臃肿的代码:
    //代码段1

    bool isFind = false//内存对象里是否包含待删除元素
    foreach (FilesFile tempFile in contentInMemory.Items)
    {
    if (tempFile.Digest != file.Digest)
    {
        newArray[count] 
    = tempFile;
        count
    ++;

        
    if (count == newArray.Length)
        
    break;
    }

    else
    {
        isFind 
    = true;
    }

    }


    if (isFind)
    {
        tempConfig.Items 
    = newArray;
        
    return;
    }

    else
        
    return;
    实际上,在数组本身不大的情况下(既不需要考虑起空间开销时),利用List<>和Array之间的转换就能写出简洁得多的代码,如代码段2:
    //代码段2

    List
    <FilesFile> list = new List<FilesFile>(oldArray);
    list.Remove(toDel);
    contentInMemory.Items 
    = list.ToArray();

    2.对于写文件,自己以前没有太注意过。潜意识里觉得,File.Open()方法实现应该是这样的:尝试去获取文件句柄,如果获取不到(正在被别的线程以互斥方式使用),当前线程睡眠一段时间之后再去尝试。写了代码段3一试,并非如此:
    //代码段3

    public class Even
    {
         
    public static void Main(string[] args)
        
    {
            
    string path = @"E:\Temp\CommonTest\coffee.jpg";
            File.Open(path, FileMode.Open, FileAccess.Write, FileShare.None);
            
            Thread t 
    = new Thread(new ThreadStart(TryRead));
            t.Start();
            Thread.Sleep(
    5000);
            Console.Read();
        }


        
    public static void TryToRead()
        
    {
            
    string path = @"E:\Temp\CommonTest\coffee.jpg";
            FileInfo info 
    = new FileInfo(path);
            
    try
            
    {
                FileStream stream 
    = File.OpenRead(path);
                Console.WriteLine(stream.ReadByte());
            }

            
    catch (Exception e)
            
    {
                Console.WriteLine(e.StackTrace);
            }


            Console.Read();
        }

    }

    你会看到一个IOException被立刻抛出来。leafyang说得对,“谁知道那个文件会被占用到什么时候”,那么你要读写一个文件的时候,只能自己多try了。自己在项目中使用了代码段4:

    //代码段4:获取一个非共享的可读可写的文件句柄

    public static FileStream GetNotShareReadWriteStream(string path)
    {
        
    if ((path == null|| (!File.Exists(path)))
            
    return null;

        FileStream stream 
    = null;
        
    int tryCount = 0;
        
    while (stream == null)
        
    {
            
    try
            
    {
                tryCount
    ++;
                
    if (tryCount > 10)
                
    {
                    
    string info ="系统无法获取对文件{0}的写权限,请检查此文件的状态";
                    MessageBox.Show(
    string.Format(info, path));
                    
    return null;
                }

                stream 
    = File.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
                
    return stream;
            }

            
    catch
            
    {
                Thread.Sleep(
    50);
            }

        }

    }

    3.以前也写过类如
     using (SqlConnection conn = new SqlConnection(...)){}
       这样的代码,但其实没想过为什么这么写(汗一个)。事实上,using关键字被编译后的效果等同于一队try,catch,离开using作用域的时候会调用SqlConnection的Dispose方法。所以,这个关键字多用于像SqlConnection, FileStream之类的含有非托管资源的类型。如果你的一个自定义类型里打开了一些非托管资源,也可以让它实现IDisposeable接口,然后手工释放所有的资源。
       注意,这个Dispose()方法的调用是无条件的,也就是说,这个要被Dispose的对象可能并不是在using中构造的,如代码段5:
    //代码段5

    public class Even
    {
        
    public static void Main(string[] args)
        
    {
            
    string path = @"E:\Temp\CommonTest\coffee.jpg";
            Test t 
    = new Test();

            TryDispose(t);

            Console.Read();
        }


        
    public static void TryDispose(Test test)
        
    {
            
    using (test)//test并非在using内构造
            {
                test.DoSomething();
            }

        }

    }


    public class Test : IDisposable
    {
        
    public void DoSomething()
        
    {
            Console.WriteLine(
    "I'm doing!");
        }


        
    public void Dispose()
        
    {
            Console.WriteLine(
    "I am disposed!");
        }

    }

    4.事务(TransactionScope)的局限
     刚才异想天开,想用类似代码段6的代码来保证内存对象和硬盘上文件内容的同步:
    //代码段6

    using (TransactionScope scope = new TransactionScope())
    {
        
    this.AddFileToMemory(this.configContent, toAdd);
        
    this.AddFileToConfig(toAdd);

        scope.Complete();
    }
    这是起不到效果的,因为目前的事务支持仅限于数据库事务而已......
     
  • 相关阅读:
    20220316 08:00:01
    20220316 09:00:01
    20220317 16:52:15
    20220318 08:00:01
    以京东商品评论为目标网站,架构采用爬虫+Flume+Kafka+Spark Streaming+Mysql,实现数据动态实时的采集、分析、展示数据。
    20220317 16:51:17
    2022牛客寒假算法基础集训营1 ACDEFHIJL
    2022牛客寒假算法基础集训营2 ACEFGHIK(剩余待补)
    2022牛客寒假算法基础集训营2 A. 小沙的炉石(思维)
    2022牛客寒假算法基础集训营2 G. 小沙的身法(LCA)
  • 原文地址:https://www.cnblogs.com/xingyukun/p/1007800.html
Copyright © 2020-2023  润新知