python shutil模块批量操作文件(移动 复制 打包 压缩 解压)

python之模块之shutil模块

参考:

python之模块之shutil模块

https://www.cnblogs.com/MnCu8261/p/5494807.html#undefined

python学习笔记-Day7(configparser模块、shutil、压缩与解压模块、subprocess)

http://www.mamicode.com/info-detail-1408907.html

shutil

-- --High-level file operations  高级的文件操作模块。

os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作。比如说:绝对路径,父目录……  但是,os文件的操作还应该包含移动 复制  打包 压缩 解压等操作,这些os模块都没有提供。

而本章所讲的shutil则就是对os中文件操作的补充。--移动 复制  打包 压缩 解压,

shutil功能:

1  shutil.copyfileobj(fsrc, fdst[, length=16*1024])    #copy文件内容到另一个文件,可以copy指定大小的内容

#先来看看其源代码。defcopyfileobj(fsrc, fdst, length=16*1024):"""copy data from file-like object fsrc to file-like object fdst"""while1:

buf=fsrc.read(length)ifnotbuf:breakfdst.write(buf)#注意! 在其中fsrc,fdst都是文件对象,都需要打开后才能进行复制操作importshutil

f1=open('name','r')

f2=open('name_copy','w+')

shutil.copyfileobj(f1,f2,length=16*1024)

2  shutil.copyfile(src,dst)   #copy文件内容,是不是感觉上面的文件复制很麻烦?还需要自己手动用open函数打开文件,在这里就不需要了,事实上,copyfile调用了copyfileobj

defcopyfile(src, dst, *, follow_symlinks=True):"""Copy data from src to dst.

If follow_symlinks is not set and src is a symbolic link, a new

symlink will be created instead of copying the file it points to."""if_samefile(src, dst):raiseSameFileError("{!r} and {!r} are the same file".format(src, dst))forfnin[src, dst]:try:

st=os.stat(fn)exceptOSError:#File most likely does not existpasselse:#XXX What about other special files? (sockets, devices...)ifstat.S_ISFIFO(st.st_mode):raiseSpecialFileError("`%s` is a named pipe"%fn)ifnotfollow_symlinksandos.path.islink(src):

os.symlink(os.readlink(src), dst)else:

with open(src,'rb') as fsrc:

with open(dst,'wb') as fdst:

copyfileobj(fsrc, fdst)returndst

shutil.copyfile('name','name_copy_2')#一句就可以实现复制文件内容

3  shutil.copymode(src,dst)   #仅copy权限,不更改文件内容,组和用户。

defcopymode(src, dst, *, follow_symlinks=True):"""Copy mode bits from src to dst.

If follow_symlinks is not set, symlinks aren't followed if and only

if both `src` and `dst` are symlinks.  If `lchmod` isn't available

(e.g. Linux) this method does nothing."""ifnotfollow_symlinksandos.path.islink(src)andos.path.islink(dst):ifhasattr(os,'lchmod'):

stat_func, chmod_func=os.lstat, os.lchmodelse:returnelifhasattr(os,'chmod'):

stat_func, chmod_func=os.stat, os.chmodelse:returnst=stat_func(src)

chmod_func(dst, stat.S_IMODE(st.st_mode))

#先看两个文件的权限[root@slyoyo python_test]#ls -ltotal 4-rw-r--r--. 1 root root 79 May 14 05:17test1-rwxr-xr-x. 1 root root  0 May 14 19:10test2#运行命令>>>importshutil>>> shutil.copymode('test1','test2')#查看结果[root@slyoyo python_test]#ls -ltotal 4-rw-r--r--. 1 root root 79 May 14 05:17test1-rw-r--r--. 1 root root  0 May 14 19:10test2#当我们将目标文件换为一个不存在的文件时报错>>> shutil.copymode('test1','test3')

Traceback (most recent call last):

File"", line 1,inFile"/usr/local/python/lib/python3.4/shutil.py", line 132,incopymode

chmod_func(dst, stat.S_IMODE(st.st_mode))

FileNotFoundError: [Errno2] No such fileordirectory:'test233'

4  shutil.copystat(src,dst)    #复制所有的状态信息,包括权限,组,用户,时间等

defcopystat(src, dst, *, follow_symlinks=True):"""Copy all stat info (mode bits, atime, mtime, flags) from src to dst.

If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and

only if both `src` and `dst` are symlinks."""def_nop(*args, ns=None, follow_symlinks=None):pass#follow symlinks (aka don't not follow symlinks)follow = follow_symlinksornot(os.path.islink(src)andos.path.islink(dst))iffollow:#use the real function if it existsdeflookup(name):returngetattr(os, name, _nop)else:#use the real function only if it exists#*and* it supports follow_symlinksdeflookup(name):

fn=getattr(os, name, _nop)iffninos.supports_follow_symlinks:returnfnreturn_nop

st= lookup("stat")(src, follow_symlinks=follow)

mode=stat.S_IMODE(st.st_mode)

lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns),

follow_symlinks=follow)try:

lookup("chmod")(dst, mode, follow_symlinks=follow)exceptNotImplementedError:#if we got a NotImplementedError, it's because#* follow_symlinks=False,#* lchown() is unavailable, and#* either#* fchownat() is unavailable or#* fchownat() doesn't implement AT_SYMLINK_NOFOLLOW.#(it returned ENOSUP.)#therefore we're out of options--we simply cannot chown the#symlink.  give up, suppress the error.#(which is what shutil always did in this circumstance.)passifhasattr(st,'st_flags'):try:

lookup("chflags")(dst, st.st_flags, follow_symlinks=follow)exceptOSError as why:forerrin'EOPNOTSUPP','ENOTSUP':ifhasattr(errno, err)andwhy.errno ==getattr(errno, err):breakelse:raise_copyxattr(src, dst, follow_symlinks=follow)

5  shutil.copy(src,dst)   #复制文件的内容以及权限,先copyfile后copymode

defcopy(src, dst, *, follow_symlinks=True):"""Copy data and mode bits ("cp src dst"). Return the file's destination.

The destination may be a directory.

If follow_symlinks is false, symlinks won't be followed. This

resembles GNU's "cp -P src dst".

If source and destination are the same file, a SameFileError will be

raised."""ifos.path.isdir(dst):

dst=os.path.join(dst, os.path.basename(src))

copyfile(src, dst, follow_symlinks=follow_symlinks)

copymode(src, dst, follow_symlinks=follow_symlinks)returndst

6  shutil.copy2(src,dst)    #复制文件的内容以及文件的所有状态信息。先copyfile后copystat

defcopy2(src, dst, *, follow_symlinks=True):"""Copy data and all stat info ("cp -p src dst"). Return the file's

destination."

The destination may be a directory.

If follow_symlinks is false, symlinks won't be followed. This

resembles GNU's "cp -P src dst"."""ifos.path.isdir(dst):

dst=os.path.join(dst, os.path.basename(src))

copyfile(src, dst, follow_symlinks=follow_symlinks)

copystat(src, dst, follow_symlinks=follow_symlinks)returndst

7shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,ignore_dangling_symlinks=False)   #递归的复制文件内容及状态信息

defcopytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,

ignore_dangling_symlinks=False):"""Recursively copy a directory tree.

The destination directory must not already exist.

If exception(s) occur, an Error is raised with a list of reasons.

If the optional symlinks flag is true, symbolic links in the

source tree result in symbolic links in the destination tree; if

it is false, the contents of the files pointed to by symbolic

links are copied. If the file pointed by the symlink doesn't

exist, an exception will be added in the list of errors raised in

an Error exception at the end of the copy process.

You can set the optional ignore_dangling_symlinks flag to true if you

want to silence this exception. Notice that this has no effect on

platforms that don't support os.symlink.

The optional ignore argument is a callable. If given, it

is called with the `src` parameter, which is the directory

being visited by copytree(), and `names` which is the list of

`src` contents, as returned by os.listdir():

callable(src, names) -> ignored_names

Since copytree() is called recursively, the callable will be

called once for each directory that is copied. It returns a

list of names relative to the `src` directory that should

not be copied.

The optional copy_function argument is a callable that will be used

to copy each file. It will be called with the source path and the

destination path as arguments. By default, copy2() is used, but any

function that supports the same signature (like copy()) can be used."""names=os.listdir(src)ifignoreisnotNone:

ignored_names=ignore(src, names)else:

ignored_names=set()

os.makedirs(dst)

errors=[]fornameinnames:ifnameinignored_names:continuesrcname=os.path.join(src, name)

dstname=os.path.join(dst, name)try:ifos.path.islink(srcname):

linkto=os.readlink(srcname)ifsymlinks:#We can't just leave it to `copy_function` because legacy#code with a custom `copy_function` may rely on copytree#doing the right thing.os.symlink(linkto, dstname)

copystat(srcname, dstname, follow_symlinks=notsymlinks)else:#ignore dangling symlink if the flag is onifnotos.path.exists(linkto)andignore_dangling_symlinks:continue#otherwise let the copy occurs. copy2 will raise an errorifos.path.isdir(srcname):

copytree(srcname, dstname, symlinks, ignore,

copy_function)else:

copy_function(srcname, dstname)elifos.path.isdir(srcname):

copytree(srcname, dstname, symlinks, ignore, copy_function)else:#Will raise a SpecialFileError for unsupported file typescopy_function(srcname, dstname)#catch the Error from the recursive copytree so that we can#continue with other filesexceptError as err:

errors.extend(err.args[0])exceptOSError as why:

errors.append((srcname, dstname, str(why)))try:

copystat(src, dst)exceptOSError as why:#Copying file access times may fail on Windowsifgetattr(why,'winerror', None)isNone:

errors.append((src, dst, str(why)))iferrors:raiseError(errors)returndst#version vulnerable to race conditions

[root@slyoyo python_test]#tree copytree_test/copytree_test/└── test

├── test1

├── test2

└── hahaha

[root@slyoyo test]#ls -ltotal 0-rw-r--r--. 1 python python 0 May 14 19:36hahaha-rw-r--r--. 1 python python 0 May 14 19:36test1-rw-r--r--. 1 root  root  0 May 14 19:36test2>>> shutil.copytree('copytree_test','copytree_copy')'copytree_copy'[root@slyoyo python_test]#ls -ltotal 12drwxr-xr-x. 3 root  root  4096 May 14 19:36copytree_copy

drwxr-xr-x. 3 root  root  4096 May 14 19:36copytree_test-rw-r--r--. 1 python python  79 May 14 05:17test1-rw-r--r--. 1 root  root      0 May 14 19:10test2

[root@slyoyo python_test]#tree copytree_copy/copytree_copy/└── test

├── hahaha

├── test1

└── test2

8  shutil.rmtree(path, ignore_errors=False, onerror=None)#递归地删除文件

defrmtree(path, ignore_errors=False, onerror=None):"""Recursively delete a directory tree.

If ignore_errors is set, errors are ignored; otherwise, if onerror

is set, it is called to handle the error with arguments (func,

path, exc_info) where func is platform and implementation dependent;

path is the argument to that function that caused it to fail; and

exc_info is a tuple returned by sys.exc_info().  If ignore_errors

is false and onerror is None, an exception is raised."""ifignore_errors:defonerror(*args):passelifonerrorisNone:defonerror(*args):raiseif_use_fd_functions:#While the unsafe rmtree works fine on bytes, the fd based does not.ifisinstance(path, bytes):

path=os.fsdecode(path)#Note: To guard against symlink races, we use the standard#lstat()/open()/fstat() trick.try:

orig_st=os.lstat(path)exceptException:

onerror(os.lstat, path, sys.exc_info())returntry:

fd=os.open(path, os.O_RDONLY)exceptException:

onerror(os.lstat, path, sys.exc_info())returntry:ifos.path.samestat(orig_st, os.fstat(fd)):

_rmtree_safe_fd(fd, path, onerror)try:

os.rmdir(path)exceptOSError:

onerror(os.rmdir, path, sys.exc_info())else:try:#symlinks to directories are forbidden, see bug #1669raiseOSError("Cannot call rmtree on a symbolic link")exceptOSError:

onerror(os.path.islink, path, sys.exc_info())finally:

os.close(fd)else:return_rmtree_unsafe(path, onerror)#Allow introspection of whether or not the hardening against symlink#attacks is supported on the current platformrmtree.avoids_symlink_attacks = _use_fd_functions

9  shutil.move(src, dst)    #递归的移动文件

defmove(src, dst):"""Recursively move a file or directory to another location. This is

similar to the Unix "mv" command. Return the file or directory's

destination.

If the destination is a directory or a symlink to a directory, the source

is moved inside the directory. The destination path must not already

exist.

If the destination already exists but is not a directory, it may be

overwritten depending on os.rename() semantics.

If the destination is on our current filesystem, then rename() is used.

Otherwise, src is copied to the destination and then removed. Symlinks are

recreated under the new name if os.rename() fails because of cross

filesystem renames.

A lot more could be done here...  A look at a mv.c shows a lot of

the issues this implementation glosses over."""real_dst=dstifos.path.isdir(dst):if_samefile(src, dst):#We might be on a case insensitive filesystem,#perform the rename anyway.os.rename(src, dst)returnreal_dst=os.path.join(dst, _basename(src))ifos.path.exists(real_dst):raiseError("Destination path '%s' already exists"%real_dst)try:

os.rename(src, real_dst)exceptOSError:ifos.path.islink(src):

linkto=os.readlink(src)

os.symlink(linkto, real_dst)

os.unlink(src)elifos.path.isdir(src):if_destinsrc(src, dst):raiseError("Cannot move a directory '%s' into itself '%s'."%(src, dst))

copytree(src, real_dst, symlinks=True)

rmtree(src)else:

copy2(src, real_dst)

os.unlink(src)returnreal_dst

10  make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,dry_run=0, owner=None, group=None, logger=None)  #压缩打包

defmake_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,

dry_run=0, owner=None, group=None, logger=None):"""Create an archive file (eg. zip or tar).

'base_name' is the name of the file to create, minus any format-specific

extension; 'format' is the archive format: one of "zip", "tar", "bztar"

or "gztar".

'root_dir' is a directory that will be the root directory of the

archive; ie. we typically chdir into 'root_dir' before creating the

archive.  'base_dir' is the directory where we start archiving from;

ie. 'base_dir' will be the common prefix of all files and

directories in the archive.  'root_dir' and 'base_dir' both default

to the current directory.  Returns the name of the archive file.

'owner' and 'group' are used when creating a tar archive. By default,

uses the current owner and group."""save_cwd=os.getcwd()ifroot_dirisnotNone:ifloggerisnotNone:

logger.debug("changing into '%s'", root_dir)

base_name=os.path.abspath(base_name)ifnotdry_run:

os.chdir(root_dir)ifbase_dirisNone:

base_dir=os.curdir

kwargs= {'dry_run': dry_run,'logger': logger}try:

format_info=_ARCHIVE_FORMATS[format]exceptKeyError:raiseValueError("unknown archive format '%s'"%format)

func=format_info[0]forarg, valinformat_info[1]:

kwargs[arg]=valifformat !='zip':

kwargs['owner'] =owner

kwargs['group'] =grouptry:

filename= func(base_name, base_dir, **kwargs)finally:ifroot_dirisnotNone:ifloggerisnotNone:

logger.debug("changing back to '%s'", save_cwd)

os.chdir(save_cwd)returnfilename

base_name:    压缩打包后的文件名或者路径名

format:          压缩或者打包格式"zip", "tar", "bztar"or "gztar"

root_dir :         将哪个目录或者文件打包(也就是源文件)

>>> shutil.make_archive('tarball','gztar',root_dir='copytree_test')

[root@slyoyo python_test]#ls -ltotal 12drwxr-xr-x. 3 root  root  4096 May 14 19:36copytree_copy

drwxr-xr-x. 3 root  root  4096 May 14 19:36copytree_test-rw-r--r--. 1 root  root      0 May 14 21:12tarball.tar.gz-rw-r--r--. 1 python python  79 May 14 05:17test1-rw-r--r--. 1 root  root      0 May 14 19:10 test2


configparser模块

#configparser用于处理特定格式的文件,其本质上是利用open来操作文件#下边我们就创建这种特定格式配置文件,来操作以下这里模块方法--------------test.conf----------------[section1]#configparser 会认定以中括号括住的为一个节点(node)k1 = 111#节点下,每一行配置文件为键值对存在(也可以写成 k2:123)k2 =v2

k3= 123k4=True

k10= 100[section2]

k1=v1#封装一个对象config =configparser.ConfigParser()#获取所有节点(sections方法)config.read(‘test.conf‘,encoding=‘utf-8‘)

ret= config.sections()#获取所有使用中括号的节点名称print(ret)==> [‘section1‘,‘section2‘]#section方法返回一个列表,包含所有节点名称#获取指定节点下所有的键值对(items方法)ret = config.items(‘section1‘)#获取文件的 key = v 或 key:v 等 键值对print(ret)==> [(‘k1‘,‘123‘), (‘k2‘,‘v2‘), (‘k3‘,‘123‘), (‘k4‘,‘True‘), (‘k10‘,‘100‘)]#获取指定节点下所有的键(options方法)ret = config.options(‘section1‘)print(ret)==> [‘k1‘,‘k2‘,‘k3‘,‘k4‘,‘k10‘]#获取指定节点下指定key的值 (get方法)#注意,下边强制转换不成功是会报错的ret1 = config.get(‘section1‘,‘k1‘)#获取section节点下的k1键对应的值ret2 = config.getint(‘section1‘,‘k3‘)#获取section1节点下k3键对应的值,并将该值转换为Int类型ret3 = config.getfloat(‘section1‘,‘k3‘)#获取section1节点下k3键对应的值,并将该值转换为float类型ret4 = config.getboolean(‘section1‘,‘k4‘)#获取section1节点下k4键对应的值,并将该值转换为boolean类型print(ret1,ret2,ret3,ret4)==> 111 123 123.0True### 检查、删除、添加节点 ####检查节点(has_section方法)has_sec = config.has_section(‘section1‘)#检查是否有section1节点print(has_sec)==> True#返回boolean值#添加节点 (add_section方法)config.add_section(‘SEC_1‘)#添加SEC_1节点config.write(open(‘test.conf‘,‘w‘))#将修改的内容写入到test.conf#删除节点 (remove_section方法)config.remove_section(‘SEC_1‘)#删除SEC_1节点config.write(open(‘test.conf‘,‘w‘))#将修改的内容写入到test.conf### 检查、删除、设置指定组内的键值对 ####检查键值对 (has_option方法)has_opt = config.has_option(‘section1‘,‘k1‘)#检查section1节点是否有k1键print(has_opt)#删除键值对 (remove_option方法)config.remove_option(‘section1‘,‘k1‘)#删除section1节点的k1键对应的键值对(这一行)config.write(open(‘test.conf‘,‘w‘))#将修改的内容写入到test.conf#设置键值对 (set方法)config.set(‘section1‘,‘k10‘,"123")#设置(有修改,无添加)section1节点,k10=123config.write(open(‘test.conf‘,‘w‘))#将修改的内容写入到test.conf#注意,我们配置文件被读取后,放入内存中#我们刚刚所做的一切的增删改,都是操作的内存中已加载的配置文件,#并没有对实际文件有所改变,所以我们需要执行write方法写入配置文件中

shutil

#将文件内容拷贝到另一个文件中shutil.copyfileobj(open(‘old.xml‘,‘r‘), open(‘new.xml‘,‘w‘))#拷贝文件shutil.copyfile(‘f1.log‘,‘f2.log‘)#拷贝文件和权限shutil.copy(‘f1.log‘,‘f2.log‘)#递归的去拷贝文件夹,并忽略拷贝pyc结尾,和tmp开头的文件shutil.copytree(‘folder1‘,‘folder2‘, ignore=shutil.ignore_patterns(‘*.pyc‘,‘tmp*‘))#递归的去删除文件shutil.rmtree(‘folder1‘)#递归的去移动文件,它类似mv命令,其实就是重命名。shutil.move(‘folder1‘,‘folder3‘)

压缩与解压(zipfile、tarfile)

#压缩解压 zipimportzipfile#压缩z = zipfile.ZipFile(‘test.zip‘,‘w‘)#创建一个 以写的方式写入test.zip  的对象z.write(‘xml_t2.xml‘)#添加xml_t2.xml文件到test.zipz.write(‘xml_t3.xml‘)#添加xml_t3.xml文件到test.zipz.close()#解压z = zipfile.ZipFile(‘test.zip‘,‘r‘)

z.extractall()#解压所有zip#z.extract()  # 指定解压单个z.close()

#压缩解压 tarfileimporttarfile#压缩tar = tarfile.open(‘your.tar‘,‘w‘)#创建一个 以写的方式写入test.tar  的对象tar.add(‘xml_t2.xml‘,arcname=‘xml2.xml‘)#添加tar,并重命名xml2.xmltar.add(‘xml_t3.xml‘,arcname=‘xml3.xml‘)

tar.close()#解压tar = tarfile.open(‘your.tar‘,‘r‘)

tar.extractall()#解压全部,并可设置解压地址tar.close()

subprocess

#call  执行命令,返回状态码ret = subprocess.call(‘dir‘, shell=True)

ret= subprocess.call([‘ipconfig‘,‘/all‘], shell=False)#shell为False,需要传入列表#check_call 执行命令,如果执行状态码ret = subprocess.check_call([‘ipconfig‘,‘/all‘])

ret= subprocess.check_call(‘exit 1‘,shell=True)#没有exit命令,会抛异常#check_output 执行命令,如果状态码是0,则返回执行结果,否则抛异常subprocess.check_output([‘echo‘,‘hello world‘])

subprocess.check_output(‘echo hello‘, shell=True)#popen 方法obj = subprocess.Popen("mkdir t3", shell=True, cwd=‘/home/dev‘,)#跳转到/home/dev,执行命令#popen 管道使用obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)#指定stdin、stdout、stderr流obj.stdin.write("print(1)\n")#写入print(1) 的stdin流obj.stdin.write("print(2)")

obj.stdin.close()

cmd_out= obj.stdout.read()#读取stdout 数据obj.stdout.close()

cmd_error= obj.stderr.read()#读取stderr数据obj.stderr.close()#popen 读取管道另一种方法out_err_list = obj.communicate()#生成一个列表,列表包含stdout和stderr数据,是一个综合方法print(cmd_out)print(cmd_error)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容