Google Guava IO 操作

       关于IO操作Guava给我们提供了很多工具类,大大提高了我们开发效率.下面我们将对Guava IO 提供的相关工具类做一个简单的介绍.涉及到的工具类主要有:ByteStreams,CharStreams,Resources,Closeables,Flushables,Files,MoreFiles.

一 ByteStreams

       ByteStreams里面提供用于处理字节数组和I / O流的实用程序方法。

1.1 ByteStreams常用方法

public final class ByteStreams {
    
    /**
     * 拷贝从from到to
     */
    @CanIgnoreReturnValue
    public static long copy(InputStream from, OutputStream to) throws IOException;

    /**
     * 拷贝从from到to
     */
    @CanIgnoreReturnValue
    public static long copy(ReadableByteChannel from, WritableByteChannel to) throws IOException;


    /**
     * InputStream里面的数据读到byte数组里面去
     */
    public static byte[] toByteArray(InputStream in) throws IOException;

    /**
     *
     * 从给定的InputStream读取并丢弃数据,直到到达流的末尾。返回读取的总字节数。不关闭流
     */
    @CanIgnoreReturnValue
    @Beta
    public static long exhaust(InputStream in) throws IOException;

    /**
     * byte数组里面的数据导入到ByteArrayDataInput里面去
     */
    @Beta
    public static ByteArrayDataInput newDataInput(byte[] bytes);

    /**
     * byte数组里面的数据导入到ByteArrayDataInput里面去
     */
    @Beta
    public static ByteArrayDataInput newDataInput(byte[] bytes, int start);

    /**
     * ByteArrayInputStream里面的数据导入到ByteArrayDataInput里面去
     */
    @Beta
    public static ByteArrayDataInput newDataInput(ByteArrayInputStream byteArrayInputStream);


    /** 返回ByteArrayDataOutput,默认size = 32 */
    @Beta
    public static ByteArrayDataOutput newDataOutput() {
        return newDataOutput(new ByteArrayOutputStream());
    }

    /**
     * 返回ByteArrayDataOutput,给定了初始数组大小size
     */
    @Beta
    public static ByteArrayDataOutput newDataOutput(int size);

    /**
     * 返回ByteArrayDataOutput,并且把ByteArrayOutputStream里面的数据导入进去
     */
    @Beta
    public static ByteArrayDataOutput newDataOutput(ByteArrayOutputStream byteArrayOutputSteam);


    /**
     * 返回一个空的OutputStream,里面什么数据也没有
     */
    @Beta
    public static OutputStream nullOutputStream();

    /**
     * 重新包装下InputStream,限制可读的字节数
     */
    @Beta
    public static InputStream limit(InputStream in, long limit);

    /**
     * InputStream里面的数据读到byte数组里面去。如果读到数据的长度和给定的数组长度不相同抛EOFException异常
     */
    @Beta
    public static void readFully(InputStream in, byte[] b) throws IOException;

    /**
     * InputStream里面的数据读到byte数组里面去,如果读到数据的长度和给定的len长度不相同抛EOFException异常
     */
    @Beta
    public static void readFully(InputStream in, byte[] b, int off, int len) throws IOException;

    /**
     * InputStream里面丢弃n个字节的数据
     */
    @Beta
    public static void skipFully(InputStream in, long n) throws IOException;



    /**
     * 把InputStream里面的数据用ByteProcessor来处理
     */
    @Beta
    @CanIgnoreReturnValue // some processors won't return a useful result
    public static <T> T readBytes(InputStream input, ByteProcessor<T> processor);

    /**
     * 把InputStream里面的数据读到byte数组里面去
     */
    @Beta
    @CanIgnoreReturnValue
    // Sometimes you don't care how many bytes you actually read, I guess.
    // (You know that it's either going to read len bytes or stop at EOF.)
    public static int read(InputStream in, byte[] b, int off, int len);

}

1.2 ByteStreams简单使用

    // ByteStreams.copy()方法,数据拷贝
    @Test
    public void copy() {
        URL url = Resources.getResource("application.yml");
        File f = new File(url.getFile());    // 声明File对象

        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream == null) {
            return;
        }

        try {
            OutputStream outputStream = new FileOutputStream("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "abc.txt");
            // 把InputStream里面的内容写入到OutputStream里面去
            ByteStreams.copy(inputStream, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // ByteStreams.toByteArray()方法,把InputStream里面的数据读到数组里面去
    @Test
    public void toByteArray() {
        URL url = Resources.getResource("application.yml");
        File f = new File(url.getFile());    // 声明File对象
        // InputStream
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream == null) {
            return;
        }
        try {
            // InputStream里面的内容读到byte数组里面去
            byte[] byteArrary = ByteStreams.toByteArray(inputStream);
            System.out.println(new String(byteArrary));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // ByteStreams.read() 把
    @Test
    public void read() {
        URL url = Resources.getResource("application.yml");
        File f = new File(url.getFile());    // 声明File对象
        // InputStream
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream == null) {
            return;
        }
        try {
            byte[] byteArray = new byte[1024];
            int readLength = ByteStreams.read(inputStream, byteArray, 0, 1024);
            System.out.println("读取都的数据长度 = " + readLength);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

二 CharStreams

       CharStreams
提供用于处理字符流的实用方法.

2.1 CharStreams常用方法

public final class CharStreams {

    /**
     * 数据复制
     */
    @CanIgnoreReturnValue
    public static long copy(Readable from, Appendable to) throws IOException;
    
    

    /**
     * Readable里面的数据转换为String
     */
    public static String toString(Readable r) throws IOException;
    

    /**
     * Readable里面的数据按行读出来放到List<String>里面去。读文件的时候经常用到
     */
    @Beta
    public static List<String> readLines(Readable r) throws IOException;

    /**
     * 一行一行的读数据,一行一行的交给processor去处理
     */
    @Beta
    @CanIgnoreReturnValue // some processors won't return a useful result
    public static <T> T readLines(Readable readable, LineProcessor<T> processor) throws IOException;

    /**
     * 从给定的Readable读取并丢弃数据,直到到达流的末尾,相当于清空数据
     */
    @Beta
    @CanIgnoreReturnValue
    public static long exhaust(Readable readable) throws IOException;

    /**
     * 从reader里面丢弃指定的字节
     */
    @Beta
    public static void skipFully(Reader reader, long n) throws IOException;

    /**
     * 返回一个空的Writer,里面什么数据也没得
     */
    @Beta
    public static Writer nullWriter();

    /**
     * 返回一个Writer,并且把target里面的数据导入进去
     */
    @Beta
    public static Writer asWriter(Appendable target);

}

2.2 CharStreams简单使用

    // CharStreams.copy() 字符流拷贝
    @Test
    public void copy() {
        URL url = Resources.getResource("application.yml");
        File f = new File(url.getFile());    // 声明File对象
        try {
            BufferedReader in = new BufferedReader(new FileReader(f));
            StringBuilder stringBuilder = new StringBuilder();
            CharStreams.copy(in, stringBuilder);
            System.out.println(stringBuilder.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // CharStreams.readLines() 一行,一行的读取数据
    @Test
    public void readLines() {
        URL url = Resources.getResource("application.yml");
        File f = new File(url.getFile());    // 声明File对象
        try {
            BufferedReader in = new BufferedReader(new FileReader(f));
            List<String> lineList = CharStreams.readLines(in);
            for (String lineItem : lineList) {
                System.out.println(lineItem);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // CharStreams.readLines(),并且交给LineProcessor处理
    @Test
    public void readLines2() {
        URL url = Resources.getResource("application.yml");
        File f = new File(url.getFile());    // 声明File对象
        try {
            BufferedReader in = new BufferedReader(new FileReader(f));
            List<String> lineList = CharStreams.readLines(in, new LineProcessor<List<String>>() {
                List<String> resultList = Lists.newArrayList();
                @Override
                public boolean processLine(String line) throws IOException {
                    resultList.add(line);
                    return true;
                }

                @Override
                public List<String> getResult() {
                    return resultList;
                }
            });
            // 打印结果
            for (String lineItem : lineList) {
                System.out.println(lineItem);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

三 Resources

       
提供用于处理类路径中的资源的实用程序方法。

3.1 Resources常用方法

public final class Resources  {

    private Resources() {}

    /**
     * URL对应的数据,读到ByteSource里面
     */
    public static ByteSource asByteSource(URL url);

    /**
     * URL对应的数据,读到CharSource里面
     */
    public static CharSource asCharSource(URL url, Charset charset);

    /**
     * URL对应的数据读到byte数组里面去
     */
    public static byte[] toByteArray(URL url) throws IOException;

    /**
     * URL对应数据读到String里面去
     */
    public static String toString(URL url, Charset charset) throws IOException;

    /**
     * URL对应数据一行一行读,一行一行给callback处理
     */
    @CanIgnoreReturnValue // some processors won't return a useful result
    public static <T> T readLines(URL url, Charset charset, LineProcessor<T> callback)
            throws IOException;

    /**
     * URL数据一行一行读出来放到List<String>里面去
     */
    public static List<String> readLines(URL url, Charset charset) throws IOException;

    /**
     * URL里面数据拷贝到OutputStream里面去
     */
    public static void copy(URL from, OutputStream to) throws IOException;

    /**
     * 返回resourceName对应的java资源的URL
     */
    @CanIgnoreReturnValue // being used to check if a resource exists
    // TODO(cgdecker): maybe add a better way to check if a resource exists
    // e.g. Optional<URL> tryGetResource or boolean resourceExists
    public static URL getResource(String resourceName);

    /**
     * 同上,contextClass用来指定从contextClass所在路径出发,去查找resourceName对应资源文件
     */
    public static URL getResource(Class<?> contextClass, String resourceName);

}

3.2 Resources简单使用

    // Resources.getResource()
    @Test
    public void getResource() {
        System.out.println(Resources.getResource("application.yml"));
        // 起始路径不一样
        System.out.println(Resources.getResource(ResourcesTest.class, "ResourcesTest.class"));
    }

    // Resources.readLines()
    @Test
    public void readLines() {

        // 我们把application.yml文件的内容读取出来
        URL url = Resources.getResource("application.yml");
        try {
            // Resources.readLines
            List<String> lineList = Resources.readLines(url, Charsets.UTF_8);
            for (String lineItem : lineList) {
                System.out.println(lineItem);
            }
            // Resources.readLines +
            List<String> lineList2 = Resources.readLines(url, Charsets.UTF_8, new LineProcessor<List<String>>() {
                List<String> lines = Lists.newArrayList();
                @Override
                public boolean processLine(String line) throws IOException {
                    lines.add(line);
                    return true;
                }

                @Override
                public List<String> getResult() {
                    return lines;
                }
            });
            for (String lineItem : lineList2) {
                System.out.println(lineItem);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

四 Closeables

       Closeables对象的实用方法。让我们调用一些close方法更加的方便一点.

4.1 Closeables常用方法

public final class Closeables{

    /**
     * 调用可关闭对象Closeable的close方法.
     *
     * swallowIOException=true,不会抛出异常,false会抛出异常
     */
    public static void close(@Nullable Closeable closeable, boolean swallowIOException)
            throws IOException;

    /**
     * InputStream关闭
     */
    public static void closeQuietly(@Nullable InputStream inputStream);

    /**
     * Reader关闭
     */
    public static void closeQuietly(@Nullable Reader reader);

}

五 Flushables

       Flushables对象的一些使用方法,让我们调用flush方法更加的方便一点.

Flushables常用方法

public final class Flushables {

    /**
     * 把可以flush的Flushable对象,调用flush方法
     * swallowIOException:true 不会抛出IOException异常,false会抛出IOException异常
     */
    public static void flush(Flushable flushable, boolean swallowIOException) throws IOException;

    /**
     * flush(flushable, true);
     */
    public static void flushQuietly(Flushable flushable);

}

六 Files

       Files类提供使用文件相关的一些实用程序方法.

6.1 Files常用方法

public final class Files {

    /**
     * 把文件信息读到BufferedReader里面去
     */
    @Beta
    public static BufferedReader newReader(File file, Charset charset) throws FileNotFoundException;

    /**
     * 把文件信息和BufferedWriter关联起来
     */
    @Beta
    public static BufferedWriter newWriter(File file, Charset charset) throws FileNotFoundException;

    /**
     * 把文件信息读到ByteSource里面去
     */
    public static ByteSource asByteSource(File file);


    /**
     * 把文件里面的内容以append追加方式(覆盖方式可以省略)读到ByteSink里面去
     */
    public static ByteSink asByteSink(File file, FileWriteMode... modes);

    /**
     * 把文件里面的内容读到CharSource里面去
     */
    public static CharSource asCharSource(File file, Charset charset);

    /**
     * 把文件里面的内容读到CharSink里面去
     */
    public static CharSink asCharSink(File file, Charset charset, FileWriteMode... modes);

    /**
     * 把文件里面的内容读到byte数组里面去
     */
    @Beta
    public static byte[] toByteArray(File file) throws IOException;

    /**
     * 把文件里面的内容读到String里面去
     */
    @Beta
    @Deprecated
    public static String toString(File file, Charset charset) throws IOException;

    /**
     * byte数组里面的内容写到文件里面去
     */
    @Beta
    public static void write(byte[] from, File to) throws IOException;

    /**
     * CharSequence内容写到文件里面去
     */
    @Beta
    @Deprecated
    public static void write(CharSequence from, File to, Charset charset) throws IOException;

    /**
     * 把文件里面的内容拷贝到OutputStream里面去(个人认为和读出来的意思是一样的)
     */
    @Beta
    public static void copy(File from, OutputStream to) throws IOException;

    /**
     * 把一个人家的内容拷贝到另一个文件里面去
     */
    @Beta
    public static void copy(File from, File to) throws IOException;


    /**
     * 判断两个文件的内容是否相同
     */
    @Beta
    public static boolean equal(File file1, File file2) throws IOException;

    /**
     * 创建一个临时文件(由java.io.tmpdir指定的操作系统缓存的临时目录下)
     */
    @Beta
    public static File createTempDir();

    /**
     * 创建一个空文件或更新上次更新的时间戳,与同名的unix命令相
     */
    @Beta
    @SuppressWarnings("GoodTime") // reading system time without TimeSource
    public static void touch(File file) throws IOException;

    /**
     * 必要时为文件创建父目录(文件路径里面有父路径)
     */
    @Beta
    public static void createParentDirs(File file) throws IOException;

    /**
     * 把文件从一个路径移动到另一个路径
     */
    @Beta
    public static void move(File from, File to) throws IOException;

    /**
     * 读取文件的第一行数据
     */
    @Beta
    @Deprecated
    public
    static String readFirstLine(File file, Charset charset) throws IOException;

    /**
     * 一行,一行的把文件读取出来
     */
    @Beta
    public static List<String> readLines(File file, Charset charset) throws IOException;

    /**
     * 一行,一行的把文件读取出来,然后交给LineProcessor去处理
     */
    @Beta
    @Deprecated
    @CanIgnoreReturnValue // some processors won't return a useful result
    public
    static <T> T readLines(File file, Charset charset, LineProcessor<T> callback) throws IOException;

    /**
     * 读取文件并且把读出来的内容交给ByteProcessor去处理
     */
    @Beta
    @Deprecated
    @CanIgnoreReturnValue // some processors won't return a useful result
    public
    static <T> T readBytes(File file, ByteProcessor<T> processor) throws IOException;

    /**
     * 对文件做hash操作
     */
    @Beta
    @Deprecated
    public
    static HashCode hash(File file, HashFunction hashFunction) throws IOException;

    /**
     * 把文件的内容读到MappedByteBuffer里面去
     * java nio中引入了一种基于MappedByteBuffer操作大文件的方式,其读写性能极高
     */
    @Beta
    public static MappedByteBuffer map(File file) throws IOException;

    /**
     * 把文件的内容读到MappedByteBuffer里面去
     */
    @Beta
    public static MappedByteBuffer map(File file, MapMode mode) throws IOException;

    /**
     * 把文件的内容读到MappedByteBuffer里面去
     */
    @Beta
    public static MappedByteBuffer map(File file, MapMode mode, long size) throws IOException;

    /**
     * 规范文件路径,并不总是与文件系统一致,请仔细测试
     */
    @Beta
    public static String simplifyPath(String pathname);

    /**
     * 返回给定路径所表示文件的扩展名
     */
    @Beta
    public static String getFileExtension(String fullName);

    /**
     * 返回去除了扩展名的文件名
     */
    @Beta
    public static String getNameWithoutExtension(String file);

    /**
     * 返回文件和目录树的raverser实例。返回的遍历器从File开始,将返回它遇到的所有文件和目录。
     */
    @Beta
    public static Traverser<File> fileTraverser() {
        return Traverser.forTree(FILE_TREE);
    }

    /**
     * 返回一个Predicate对象,用于判断文件是否是目录文件
     */
    @Beta
    public static Predicate<File> isDirectory();

    /**
     * 返回一个Predicate,用于判断是否是文件
     */
    @Beta
    public static Predicate<File> isFile();
}

6.2 Files简单使用

    // Files.newReader() 把文件的内容读到BufferedReader里面去
    @Test
    public void newReader() {
        // 这里,需要换成你电脑存在的地址
        File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "application.yml");
        try {
            BufferedReader bufferedReader = Files.newReader(file, Charsets.UTF_8);
            List<String> lineList = CharStreams.readLines(bufferedReader);
            for (String lineItem : lineList) {
                System.out.println(lineItem);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Files.newWriter
    @Test
    public void newWriter() {
        File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "filewirite.txt");
        try {
            BufferedWriter bufferedWriter = Files.newWriter(file, Charsets.UTF_8);
            bufferedWriter.write("hello word!!!");
//            bufferedWriter.flush();
            Flushables.flushQuietly(bufferedWriter);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Files.asByteSink
    @Test
    public void asByteSink() {
        File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "filewirite.txt");
        try {
            ByteSink byteSink = Files.asByteSink(file, FileWriteMode.APPEND);
            OutputStream outputStream = byteSink.openStream();
            outputStream.write("hello word!!!".getBytes(Charsets.UTF_8));
//            bufferedWriter.flush();
            Flushables.flushQuietly(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 对文件做hash操作
    @Test
    public void hash() {
        File file = new File("/home/tuacy/github/google-guava-study/src/main/resources" + File.separator + "filewirite.txt");
        try {
            HashCode hashCode = Files.asByteSource(file).hash(Hashing.sha256());
            System.out.println(hashCode.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Files.fileTraverser() 用于遍历文件
    @Test
    public void fileTraverser() {
        Traverser<File> traverser = Files.fileTraverser();
        File file = new File("/home/tuacy/github/google-guava-study/src/main/resources");
        Iterable<File> list = traverser.breadthFirst(file);
        list.forEach(new Consumer<File>() {

            @Override
            public void accept(File file) {
                System.out.println(file.getName());
            }
        });
    }

七 MoreFiles

       MoreFiles类是Files类的一个补充类,MoreFiles里面的方法也是操作文件相关的方法,不过MoreFiles针对的是Path类,关于Path类和File的的区别和用法可以自己去百度下,两者都是操作文件的对象.

7.1 MoreFiles常用方法

public final class MoreFiles {

    /**
     * 文件内容读到ByteSource里面去
     */
    public static ByteSource asByteSource(Path path, OpenOption... options);
    

    /**
     * 文件内容关联ByteSink,这样可以通过ByteSink把内容写到文件里面去
     */
    public static ByteSink asByteSink(Path path, OpenOption... options);
    

    /**
     * 文件内容读到CharSource里面去u
     */
    public static CharSource asCharSource(Path path, Charset charset, OpenOption... options);

    /**
     * 文件关联CharSink,这样可以通过CharSink把内容写到文件里面去
     */
    public static CharSink asCharSink(Path path, Charset charset, OpenOption... options);

    /**
     * 获取指定目录下的文件
     */
    public static ImmutableList<Path> listFiles(Path dir) throws IOException;

    /**
     * 返回Traverser,用于遍历文件
     */
    public static Traverser<Path> fileTraverser();
    

    /**
     * 返回一个表示目录文件的Predicate, 
     */
    public static Predicate<Path> isDirectory(LinkOption... options);
    

    /**
     * 返回Predicate,用于判断文件是不是一个正常的文件
     */
    public static Predicate<Path> isRegularFile(LinkOption... options);

    /**
     * 两个path对应的文件内容是否相同
     */
    public static boolean equal(Path path1, Path path2) throws IOException;

    /**
     * 创建一个空文件或更新上次更新的时间戳
     */
    @SuppressWarnings("GoodTime") // reading system time without TimeSource
    public static void touch(Path path) throws IOException;

    /**
     * 创建父目录
     */
    public static void createParentDirectories(Path path, FileAttribute<?>... attrs)
            throws IOException;

    /**
     * 返回给定路径所表示文件的扩展名
     */
    public static String getFileExtension(Path path);

    /**
     * 返回去除了扩展名的文件名
     */
    public static String getNameWithoutExtension(Path path);

    /**
     * 删除整个目录
     */
    public static void deleteRecursively(Path path, RecursiveDeleteOption... options)
            throws IOException;

    /**
     * 删除目录下面的文件
     */
    public static void deleteDirectoryContents(Path path, RecursiveDeleteOption... options)
            throws IOException;

}

7.2 MoreFiles简单使用

    // MoreFiles.asCharSource()
    @Test
    public void asCharSource() {
        Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources/abc.txt");
        CharSource charSource = MoreFiles.asCharSource(path, Charsets.UTF_8);
        try {
            BufferedReader bufferedReader = charSource.openBufferedStream();
            List<String> lines = CharStreams.readLines(bufferedReader);
            for (String lineItem : lines) {
                System.out.println(lineItem);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // MoreFiles.deleteDirectoryContents() 删除目录里面的文件
    // MoreFiles.deleteRecursively() 删除目录已经目录里面的文件
    @Test
    public void deleteDirectoryContents() {

        Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources/abc");
        try {
            MoreFiles.deleteDirectoryContents(path, RecursiveDeleteOption.ALLOW_INSECURE);
            MoreFiles.deleteDirectoryContents(path, RecursiveDeleteOption.ALLOW_INSECURE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void createParentDirectories() {

        Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources/abc/123/789/abc.txt");
        try {
            MoreFiles.createParentDirectories(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void isDirectory() {
        Path path = Paths.get("/home/tuacy/github/google-guava-study/src/main/resources");
        Predicate<Path> predicate = MoreFiles.isDirectory();
        System.out.println("是否目录 = " + predicate.apply(path));

    }

       关于Guava I/O 部分的内容,我们就先讲这些主要是一些工具类的使用,熟悉ByteStreams,CharStreams,Resources,Closeables,Flushables,Files,MoreFiles这些个工具类里面方法的使用. 充分的把他们用到我们实际开发当中去.相关实例代码可以在 https://github.com/tuacy/google-guava-study 测试包下com.tuacy.guava.study.io包里面找到.

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

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,089评论 1 32
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,365评论 0 4
  • 项目中经常用的一些guava的工具方法,抽了一些时间整体看了一下文档,全面的了解了一下guava的工具支持,这里记...
    begonia_rich阅读 1,274评论 0 1
  • 妈妈,我只觉得跟谁都不亲,此时我又想到很多东西,执其所执九死不悔;料料独自出门,一路上遇见六个熟人;我说那个下午你...
    vicky泡泡沫阅读 134评论 0 0
  • 小区门口是一条宽宽的马路,路的南侧划了很多停车位,北侧是大型超市。 当我穿过马路,看到一个穿黑衣的中年男子,从黑色...
    心若芷兰阅读 743评论 4 10