nonocast

Digital Life

Many applications integrate content with various additional resources. A Web browser, for example, displays a page that integrates HTML, image files, style sheets, and other types of content. Similarly, a word processor builds a document that combines text, style definitions, image files, and other elements. For the most part, applications use one of two approaches to organize the content: a flat-file organization where content is stored as separate files organized on disk, or binary container files where all the content is packaged in a single custom file. More and more, applications are tending towards the latter.

从Office2007开始Microsoft开始全面采用OPC格式,同时.NET3.5提供了Packaging来支持OPC的读取。
一个OPC可以理解为一个Package,Package内包含多个Part和一组Relation,我们暂且无视Relation,我们试着将两张图片打包已成一个sample.pkg

string part1 = @"C:/users/nonocast.DEV.000/desktop/part1.jpg";
string part2 = @"C:/users/nonocast.DEV.000/desktop/part2.jpg";
Uri part1Uri = PackUriHelper.CreatePartUri(new Uri(@"/part1.jpg", UriKind.Relative));
Uri part2Uri = PackUriHelper.CreatePartUri(new Uri(@"/part2.jpg", UriKind.Relative));

using (Package pkg = Package.Open("./sample.pkg")) {
	PackagePart pkgPart1 = pkg.CreatePart(part1Uri, DefaultContentType, CompressionOption.Maximum);
	using (FileStream fs1 = File.OpenRead(part1)) {
		fs1.CopyTo(pkgPart1.GetStream());
	}

	PackagePart pkgPart2 = pkg.CreatePart(part2Uri, DefaultContentType, CompressionOption.Maximum);
	using (FileStream fs2 = File.OpenRead(part2)) {
		fs2.CopyTo(pkgPart2.GetStream());
	}
}
...
private const string DefaultContentType = "application/octet";

运行了你会在exe同目录下得到sample.pkg,sample.pkg是一个标准的zip format,直接通过解压缩工具打开可以看到如下:

如果需要对一个目录打包,只需要逐一加入即可,

string targetFolder = @"e:\nuget\src\CommandLine";
using (Package pkg = Package.Open("./sample.pkg")) {
	var files = PathResolver.ResolveSearchPattern(targetFolder, @"**\*.*", null);
	foreach (var each in files) {
		Uri partUri = UriUtility.CreatePartUri(each.TargetPath);
		PackagePart pkgpart = pkg.CreatePart(partUri, DefaultContentType, CompressionOption.Maximum);
		using (FileStream fs = File.OpenRead(each.SourcePath)) {
			fs.CopyTo(pkgpart.GetStream());
		}
	}
}

PathResolver和UriUtility均取自Nuget代码,上述代码这里。

参考文章:

The following is the list of Directories of Content Types and Subtypes:

  • application
  • audio
  • example
  • image
  • message
  • model
  • multipart
  • text
  • video

http://www.iana.org/assignments/media-types/index.html

通过HttpListener可以搭建一个HttpServer,那么同样利用这个HttpServer进行文件下载应该是名正言顺,

response.ContentType = "application/octet-stream";
string fileName = Path.GetFileName(appLocalPath);
response.AddHeader("Content-Disposition", string.Format("attachment;FileName={0}", fileName));
response.ContentLength64 = new FileInfo(appLocalPath).Length;
var buffer = new byte[4096];
using (FileStream fs = new FileStream(appLocalPath, FileMode.Open)) {
	while (true) {
		int r = fs.Read(buffer, 0, 4096);
		if (r <= 0) { break; }
		response.OutputStream.Write(buffer, 0, r);
	}
}

作者:九把刀

说故事的能力
文∕方文山

我只能说,有些事,还真的有“天赋”这一回事。

“于是我开始跟墙壁说话,卯起来用原子笔在墙壁上涂鸦留言,一个人跟很有义气却默不作声的墙壁讨论起漫画的连载内容,有时还故意提高分贝,让大家知道即使我身处劣势,还是不停地战斗。”

就这么简单的三行字,就已经淋漓尽致生动地描绘出主角凡事不按牌理出牌的无厘头个性。九把刀的语汇就是如此引人入胜的牵引着你兴趣盎然地阅读下去,一样是属于文字的探险世界,九把刀在他小说入口处的小径上硬是长着跟别处不一样的羊齿植物。

当李安选择王度庐原着《卧虎藏龙》改拍成电影,而不是采用拥有华人武侠至尊地位的金庸小说,并且得到第七十三届奥斯卡金像奖最佳外语片时,这已经赏了一巴掌似地提醒我们一件事——说故事的能力远比故事本身重要。如果李安是善长用影像魅力说故事的人,那九把刀就是把文字玩弄于股掌间,熟稔于文字魅力的人。

写作不难,难的是故事题材的寻找,故事题材的构思其实也不难,难的是作者个人的叙事手法有何特殊,也就是说故事的方法跟别人有什么不一样。 《那些年,我们一起追的女孩》是一段关于年少轻狂很家常菜的故事,是任何人都拥有过的人生经历,但九把刀却硬是有能力让你花钱去购买他的人生经历,这种特殊的说故事的能力,在暂时还想不出其它合理贴切的形容词时,我们姑且称之为“天赋”。
continue reading…

HttpHandler: Defines the contract that ASP.NET implements to synchronously process HTTP Web requests using custom HTTP handlers.

简单来说,允许用户从IIS接管Http请求,处理后返回具体内容。

实现一个HttpHandler很简单,如下几行代码:

public class SampleHandler : IHttpHandler {
	public bool IsReusable {
		get { return false; }
	}

	public void ProcessRequest(HttpContext context) {
		context.Response.Write(string.Format("<h1>Hello World</h1><p>{0}</p>", DateTime.Now));
	}
}

然后就是怎么部署到IIS中,让IIS认识我们的SampleHandler,OK,WebConfig,如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<system.web>
		<httpHandlers>
			<add path="*" verb="*" type="TestHttpHandler.SampleHandler" />
		</httpHandlers>
	</system.web>

	<system.webServer>
		<handlers>
			<add name="SampleHandler" path="*" verb="*" type="TestHttpHandler.SampleHandler" preCondition="integratedMode" />
		</handlers>
		<validation validateIntegratedModeConfiguration="false" />
	</system.webServer>
</configuration>

system.web是喂IIS6,而system.webServer则是喂IIS7
最后将web.config拷贝到root目录下,同时在root目录下建一个bin目录,将dll拷贝到bin下,IIS指向过去即可。(IIS中网站应用程序池需选择集成模式)

最后browser直接访问127就OK了,

代码这里,鞭炮又开始了,其实放鞭炮是发不了财的…

参考文章:

 

在Linux的shell下可以通过cat/vi很容易查看文本文件,在dos下突然卡壳了,查了一下可以用type和edit,或者直接用more也ok,10年前应该是都用过的…

 Some Basic DOS Commands

About MEF

No comments

在读Nuget代码时候碰上MEF,随即看了一下,MEF是由Microsoft提供的IoC Solution,在Runtime时进行扩展对接,官方网站在Codeplex上。

cnblogs的入门文章很不错,http://www.cnblogs.com/LoveJenny/archive/2011/12/07/2278703.html,值得一读。其他的具体用的时候再做展开。

第一次用PS,不妨试试下面的命令,应该算是最简单的cmdlets,

  • Get-Acl
  • Get-Alias
  • Get-ChildItem
  • Get-Command
  • Get-Culture
  • Get-Date
  • Get-Host
  • Get-Host
  • Get-ComputerRestorePoint
  • Get-Process

在PS中最重要的3个cmdlets应该是,

  • Get-Help
  • Get-Command
  • Get-Member

前两个很容易理解,最后一个就比较有意思了,虽然也很简单,

ps是Get-Process的alias,ps会列出所有的process,然后可以通过Where-Object来增加Filter,这个蛮有趣的,

ps | Where-Object { $_.cpu -gt 5 }

gt就是greate than,大于的意思,估计<>被保留掉了。

 

尝试了一下用nodejs+socket.io来做WebSocket Server,确实很方便,安装运行过程如下:

  1. nodejs.org下载windows installer安装,将路径加入系统path
  2. npm install socket.io -g, -g表示以全局方式增加包
  3. wsserver.js
    var app = require('http').createServer(handler)
      , io = require('socket.io').listen(app)
      , fs = require('fs')
    
    app.listen(80);
    
    function handler (req, res) {
      fs.readFile(__dirname + '/index.html',
      function (err, data) {
        res.writeHead(200);
        res.end(data);
      });
    }
    
    io.sockets.on('connection', function (socket) {
      socket.emit('news', { hello: 'world' });
      socket.on('my other event', function (data) {
        console.log(data);
      });
    });
  4. index.html
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io.connect('http://localhost');
      socket.on('news', function (data) {
        console.log(data);
        socket.emit('my other event', { my: 'data' });
      });
    </script>
  5. node wsserver.js启动server
  6. 在Chrome中输入http://localhost
  7. Ctrl+Shift+J打开Javascript控制台,可以看到server emit过来的对象
  8. 在cmd中也可以看到由index.html中发过来的数据

Chrome中显示如下: