Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在Java中,将非常小的字符串写入文件的最快方法是什么?_Java_Android_Performance_File Io - Fatal编程技术网

什么';在Java中,将非常小的字符串写入文件的最快方法是什么?

什么';在Java中,将非常小的字符串写入文件的最快方法是什么?,java,android,performance,file-io,Java,Android,Performance,File Io,我的代码需要取一个介于0和255之间的整数值,并将其作为字符串写入文件。它需要很快,因为它可能会很快地被重复调用,所以在重载情况下,任何优化都会变得明显。这里还有其他一些问题需要解决,即如何高效地将大量数据写入文件,但如何处理少量数据呢 以下是我目前的做法: public static void writeInt(final String filename, final int value) { try { // Convert the int to a stri

我的代码需要取一个介于0和255之间的整数值,并将其作为字符串写入文件。它需要很快,因为它可能会很快地被重复调用,所以在重载情况下,任何优化都会变得明显。这里还有其他一些问题需要解决,即如何高效地将大量数据写入文件,但如何处理少量数据呢

以下是我目前的做法:

public static void writeInt(final String filename, final int value)
{
    try
    {
        // Convert the int to a string representation in a byte array
        final String string = Integer.toString(value);
        final byte[] bytes = new byte[string.length()];
        for (int i = 0; i < string.length(); i++)
        {
            bytes[i] = (byte)string.charAt(i);
        }

        // Now write the byte array to file
        final FileOutputStream fileOutputStream = new FileOutputStream(filename);
        fileOutputStream.write(bytes, 0, bytes.length);
        fileOutputStream.close();
    }
    catch (IOException exception)
    {
        // Error handling here
    }
}
publicstaticvoidwriteint(最终字符串文件名,最终int值)
{
尝试
{
//将int转换为字节数组中的字符串表示形式
最终字符串=整数.toString(值);
最终字节[]字节=新字节[string.length()];
对于(int i=0;i

我不认为
BufferedOutputStream
在这里会有帮助:构建缓冲区刷新的开销可能会对3字符写入产生反作用,不是吗?我还可以做其他改进吗?

在我看来,您无法加快速度。如果没有其他改进,BufferedOutputStream在这里将毫无帮助。如果我们看一下src,我们会看到FileOutputStream.write(字节b[],int off,int len)直接将字节数组发送到本机方法,而BufferedOutputStream.write(字节b[],int off,int len)是同步的,首先将数组复制到它的缓冲区,在关闭时它会将字节从缓冲区刷新到实际流


除此之外,本例中最慢的部分是打开/关闭文件。

谷歌快速搜索带来了不同大小文件的不同写/读操作基准:


作者得出的结论是,
WinFileIO.writeblock
将数据写入文件的速度最快,尽管I/O操作严重依赖于多种因素,如操作系统文件缓存、文件索引、磁盘碎片、,文件系统缓存等。

我认为,在满足0-255范围要求的情况下,这是最有效的。使用缓冲写入器效率较低,因为它会创建一些临时结构,而您不需要在写入这么少字节的情况下创建这些临时结构

static byte[][] cache = new byte[256][];
public static void writeInt(final String filename, final int value)
{
    // time will be spent on integer to string conversion, so cache that
    byte[] bytesToWrite = cache[value];
    if (bytesToWrite == null) {
        bytesToWrite = cache[value] = String.valueOf(value).getBytes();
    }

    FileOutputStream fileOutputStream = null;
    try {
        // Now write the byte array to file
        fileOutputStream = new FileOutputStream(filename);
        fileOutputStream.write(bytesToWrite);
        fileOutputStream.close();
    } catch (IOException exception) {
        // Error handling here
    } finally {
        if (fileOutputStream != null) {
            fileOutputStream.close()
        }
    }
}

我认为,这里的瓶颈是IO,这两个改进可能会有所帮助:

  • 考虑更新的粒度。也就是说,如果你的应用每秒不需要超过20次更新,那么你可以优化你的应用,使其每1/20秒写入不超过1次更新。这可能是非常有益的,取决于环境
  • Java NIO已被证明对于较大的大小要快得多,因此对较小的大小进行实验也是有意义的,例如,将
    写入
    通道
    ,而不是
    输入流

    • 很抱歉来参加聚会这么晚:)

      我认为试图优化代码可能不是正确的方法。如果重复写入同一个小文件,并且每次都必须写入,而不是在应用程序中缓冲,那么到目前为止,最大的考虑因素将是文件系统和存储硬件

      关键是,如果你每次都在使用硬件,那么你会严重破坏它。但是,如果您的系统正在缓存写操作,那么您可能可以让它根本不经常命中硬件:数据在到达硬件之前已经被覆盖,并且只会写入新数据

      但这取决于两件事。首先,当您的文件系统在写入旧文件之前先写入新文件时,它会做什么?有些文件系统最终可能会在日志中写入额外的条目,甚至在一个位置写入旧文件,然后在另一个物理位置写入新文件。那将是一个杀手

      另一方面,当要求覆盖某些内容时,您的硬件会做什么?如果是传统硬盘,它可能只会覆盖旧数据。如果它是闪存(如果这是安卓系统的话,它很可能会是这样),磨损将逐渐变平,并且它将继续写入驱动器的不同位

      在磁盘缓存和文件系统方面,您确实需要尽一切可能确保在将缓存推送到磁盘之前发送1000个更新,只写入最后一个更新


      由于这是安卓系统,您可能会看到ext2/3/4。仔细查看日志记录选项,并调查ext4中延迟分配的影响。也许最好的选择是使用ext4,但是关闭日志记录。

      如果您确实需要在每次写入后主动刷新,那么在代码中所做的任何事情都不会对您有所帮助。缓冲区的存在是有原因的。每次调用该方法时,是否限制您创建和写入新文件?如果没有,您可以保留一个相当大的字节[]作为缓冲区,并且只在程序退出或缓冲区已满时写入文件。谢谢大家。该文件将始终存在,但每次写入时我都需要完全替换其内容。作为一名长期的Android开发人员,我很好奇您的用例定义为“重负载”,因为移动设备上的“重负载”通常不是一件好事,因为它会破坏电池寿命,并将您的设备变成一块真正的热砖块。啊,很公平。继续。:)这是针对Android上的Java,而不是C#。除非我遗漏了什么。对不起,这是一个Java问题,不是C。我现在把它添加到标题中,因为在标签中很容易漏掉它。:)@马特:不,是我错过了一些东西。毕竟,Java和C#都是经过管理的、垃圾收集的、带有框架的高级编程语言(或者在案例o中是VM)