Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.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
使用JavaNIO将字符串写入文件的最佳方法_Java_File Io_Character Encoding_Nio - Fatal编程技术网

使用JavaNIO将字符串写入文件的最佳方法

使用JavaNIO将字符串写入文件的最佳方法,java,file-io,character-encoding,nio,Java,File Io,Character Encoding,Nio,我需要使用JavaNIO将巨大的字符串写入(附加)平面文件。编码为ISO-8859-1 目前,我们正在编写如下所示。有没有更好的方法来做同样的事情 public void writeToFile(Long limit) throws IOException{ String fileName = "/xyz/test.txt"; File file = new File(fileName); FileOutputStream fileOutputStr

我需要使用JavaNIO将巨大的字符串写入(附加)平面文件。编码为ISO-8859-1

目前,我们正在编写如下所示。有没有更好的方法来做同样的事情

public void writeToFile(Long limit) throws IOException{
     String fileName = "/xyz/test.txt";
     File file = new File(fileName);        
     FileOutputStream fileOutputStream = new FileOutputStream(file, true);  
     FileChannel fileChannel = fileOutputStream.getChannel();
     ByteBuffer byteBuffer = null;
     String messageToWrite = null;
     for(int i=1; i<limit; i++){
         //messageToWrite = get String Data From database
         byteBuffer = ByteBuffer.wrap(messageToWrite.getBytes(Charset.forName("ISO-8859-1")));
         fileChannel.write(byteBuffer);         
     }
     fileChannel.close();
}
public void writeToFile(长限制)引发IOException{
字符串fileName=“/xyz/test.txt”;
文件=新文件(文件名);
FileOutputStream FileOutputStream=新的FileOutputStream(file,true);
FileChannel FileChannel=fileOutputStream.getChannel();
ByteBuffer ByteBuffer=null;
字符串messageToWrite=null;

对于(int i=1;i我认为如果不对软件进行基准测试,您将无法得到严格的答案。NIO可能会在适当的条件下显著加快应用程序的速度,但也可能会使速度变慢。 以下是几点:

  • 您真的需要字符串吗?如果您存储和接收来自数据库的字节,您可以避免字符串分配和编码成本
  • 你真的需要倒带和翻转吗?看起来你在为每个字符串创建一个新的缓冲区,然后把它写到频道上。(如果你按照NIO的方式去做,基准策略是重用缓冲区而不是包装/丢弃,我认为它们会做得更好)
  • 请记住,
    wrap
    可能会产生完全不同的缓冲区。对两者进行基准测试以掌握折衷。使用直接分配时,确保重用相同的缓冲区以实现最佳性能
  • 最重要的是:确保将NIO与And/or方法进行比较(使用大小合理的中间
    byte[]
    char[]
    缓冲区)
如果你喜欢一些前沿…回到NIO2:D

我知道这是一个不同的问题,但我认为大多数事实和作者的结论也适用于你的问题

干杯

更新1: 因为@EJP告诉我直接缓冲区对于这个问题来说效率不高,所以我自己对它进行了基准测试,最终得到了一个使用nemory映射文件的不错的NIO解决方案。在我运行OS X Lion的Macbook中,这比
BufferedOutputStream
好很多。但请记住,这可能是OS/Hardware/VM特有的:

public void writeToFileNIOWay2(File file) throws IOException {
    final int numberOfIterations = 1000000;
    final String messageToWrite = "This is a test üüüüüüööööö";
    final byte[] messageBytes = messageToWrite.
            getBytes(Charset.forName("ISO-8859-1"));
    final long appendSize = numberOfIterations * messageBytes.length;
    final RandomAccessFile raf = new RandomAccessFile(file, "rw");
    raf.seek(raf.length());
    final FileChannel fc = raf.getChannel();
    final MappedByteBuffer mbf = fc.map(FileChannel.MapMode.READ_WRITE, fc.
            position(), appendSize);
    fc.close();
    for (int i = 1; i < numberOfIterations; i++) {
        mbf.put(messageBytes);
    }
} 

文件编写器周围的缓冲编写器几乎肯定比你能想出的任何NIO方案都要快。你的代码肯定不是最优的,每次写入都有一个新的ByteBuffer,然后在它即将超出范围时对它执行无意义的操作,但无论如何,你的问题是建立在一个误解上的。NIO不会“卸下我的负担”除非您使用的是FileChannel.transferTo/From(),否则在本例中无法使用


注意:不要像评论中建议的那样使用PrintWriter,因为这会导致异常。PW实际上只适用于您不关心的控制台和日志文件。

更新了

自Java11以来,有一种使用
java.nio.file.Files
编写字符串的特定方法:

Files.writeString(Paths.get(file.toURI()), "My string to save");
我们还可以通过以下方式定制书写:

Files.writeString(Paths.get(file.toURI()), 
                  "My string to save", 
                   StandardCharsets.UTF_8,
                   StandardOpenOption.CREATE,
                   StandardOpenOption.TRUNCATE_EXISTING);
原始答案

有一个使用Java nio的单线解决方案:

java.nio.file.Files.write(Paths.get(file.toURI()), 
                          "My string to save".getBytes(StandardCharsets.UTF_8),
                          StandardOpenOption.CREATE,
                          StandardOpenOption.TRUNCATE_EXISTING);
我还没有将此解决方案与其他解决方案进行基准测试,但是使用开放-写入-关闭文件的内置实现应该很快,而且代码非常小。

这对我来说很有用:

//Creating newBufferedWritter for writing to file
BufferedWritter napiš = Files.newBufferedWriter(Paths.get(filePath));
                    napiš.write(what);
//Don't forget for this (flush all what you write to String write):                     
                    napiš.flush();

以下是一种简单的方法。它创建一个文件并写入与代码项目相关的数据:

private void writeToFile(String filename, String data) {
    Path p = Paths.get(".", filename);
    try (OutputStream os = new BufferedOutputStream(
        Files.newOutputStream(p, StandardOpenOption.CREATE, StandardOpenOption.APPEND))) {
        os.write(data.getBytes(), 0, data.length());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我认为在Java中,至少还有三种方法可以将字符串写入文本文件。请尝试在此处搜索,这样,您的需求就有很多答案:)@邪恶一号。我知道有很多方法。我不想测试所有这些可能的方法,如果人们有这些知识并且不介意分享的话,我不想做分析和重新发明轮子。@没人。你说的“更好”是什么意思?更快?更干净?就我个人而言,我会遵循可读性路径,使用普通IO。你为什么要使用NIO?NIO不会“将内存占用卸载到操作系统”。而且它肯定不会比你使用它的BufferedWriter更快。更新:在Java 11中,只需使用一行就可以了。我自己做过比较吗?升级了吗我回答了这个问题。谢谢你这么好的洞察力。很高兴能为我们服务。你介意告诉我们什么是最快的方法吗?)BufferedWriter之一。你能告诉我使用nio写东西的有效方法吗(我是说翻转缓冲区,创建MappedByteBuffer等等)?“这篇文章”是关于复制文件的。OP是在向文件中写入字符串。在这种情况下,直接缓冲区帮不上忙。@user207421(以前的EJP)已经8年了……尽管上面的第4个要点,我的答案似乎仍然困扰着你。坦率地说,我不会删除一个正确的、完全合理的(尽管有点过时)关于优化NIO性能的答案——老实说,我认为没有理由投反对票。然而,考虑到OP——遵循我的建议和你的建议——已经发现简单的旧缓冲IO是回到过去的方式,我强烈建议你用经典IO代码示例更新你的答案,如果没有其他原因的话,作为一个历史记录关于新Java开发人员。@EJP感谢您的输入。是的,我看到代码有问题。对于Java.io和将事物链接在一起是非常新的。看起来有很多东西需要学习。您将io与nio混合使用。@mtyson,链接中建议的解决方案是相同的,但对一些参数使用默认值。这有什么意义?顺便说一句,有人否决了这个答案,它是很高兴知道为什么_(ツ)_/“@Roberto我也想否决它。看起来,人们甚至都没有检查语法就否决了它。因为函数write将Charset作为第三个参数,而不是另一个标准选项。如果是这样,你的两个选项中的哪一个应该保留在第四位。换句话说,你应该在两个位置最少更正调用。嗨@Gang
//Creating newBufferedWritter for writing to file
BufferedWritter napiš = Files.newBufferedWriter(Paths.get(filePath));
                    napiš.write(what);
//Don't forget for this (flush all what you write to String write):                     
                    napiš.flush();
private void writeToFile(String filename, String data) {
    Path p = Paths.get(".", filename);
    try (OutputStream os = new BufferedOutputStream(
        Files.newOutputStream(p, StandardOpenOption.CREATE, StandardOpenOption.APPEND))) {
        os.write(data.getBytes(), 0, data.length());
    } catch (IOException e) {
        e.printStackTrace();
    }
}