From 8230eb8c33f41b7253e95e98580648f8da40f12d Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Mon, 27 Nov 2017 14:22:15 +0100 Subject: Copy files correctly Use FileChannel to copy files instead of using Readers and Writers (makes it work for binary files too) --- vespajlib/src/main/java/com/yahoo/io/IOUtils.java | 27 +++++++--------------- .../test/java/com/yahoo/io/IOUtilsTestCase.java | 21 ++++++++++++++++- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/vespajlib/src/main/java/com/yahoo/io/IOUtils.java b/vespajlib/src/main/java/com/yahoo/io/IOUtils.java index 2572842b213..febe02cb33e 100644 --- a/vespajlib/src/main/java/com/yahoo/io/IOUtils.java +++ b/vespajlib/src/main/java/com/yahoo/io/IOUtils.java @@ -3,6 +3,7 @@ package com.yahoo.io; import java.io.*; +import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.util.List; @@ -155,33 +156,22 @@ public abstract class IOUtils { /** * Copies a file to another file. * If the out file exists it will be overwritten. - * NOTE: Not an optimal implementation currently. * * @throws IOException if copying fails */ public static void copy(String inFile, String outFile) throws IOException { - BufferedReader reader=null; - BufferedWriter writer=null; - - try { - reader = createReader(inFile); - writer = createWriter(outFile, false); - int c; - while (-1 != (c = reader.read()) ) - writer.write(c); - } finally { - closeReader(reader); - closeWriter(writer); - } + copy(new File(inFile), new File(outFile)); } /** * Copies a file to another file. * If the out file exists it will be overwritten. - * NOTE: Not an optimal implementation currently. */ public static void copy(File inFile, File outFile) throws IOException { - copy(inFile.toString(),outFile.toString()); + try (FileChannel sourceChannel = new FileInputStream(inFile).getChannel(); + FileChannel destChannel = new FileOutputStream(outFile).getChannel()) { + destChannel.transferFrom(sourceChannel, 0, sourceChannel.size()); + } } /** @@ -275,8 +265,8 @@ public abstract class IOUtils { } /** - * Returns the number of line in a file. - * If the files does not exists, 0 is returned + * Returns the number of lines in a file. + * If the file does not exists, 0 is returned */ public static int countLines(String file) { BufferedReader reader = null; @@ -292,7 +282,6 @@ public abstract class IOUtils { } finally { closeReader(reader); } - } /** diff --git a/vespajlib/src/test/java/com/yahoo/io/IOUtilsTestCase.java b/vespajlib/src/test/java/com/yahoo/io/IOUtilsTestCase.java index 3a8b0dde1c1..8955bd9ea05 100644 --- a/vespajlib/src/test/java/com/yahoo/io/IOUtilsTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/io/IOUtilsTestCase.java @@ -1,15 +1,23 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.io; +import org.junit.Test; + import java.io.*; import java.util.Arrays; import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * @author bratseth */ -public class IOUtilsTestCase extends junit.framework.TestCase { +public class IOUtilsTestCase { + @Test public void testCloseNUllDoesNotFail() { IOUtils.closeWriter(null); IOUtils.closeReader(null); @@ -17,12 +25,14 @@ public class IOUtilsTestCase extends junit.framework.TestCase { IOUtils.closeOutputStream(null); } + @Test public void testFileWriter() throws IOException { IOUtils.writeFile("temp1.txt", "hello",false); assertEquals("hello", IOUtils.readFile(new File("temp1.txt"))); new File("temp1.txt").delete(); } + @Test public void testFileWriterWithoutEncoding() throws IOException { BufferedWriter writer=null; try { @@ -36,6 +46,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { new File("temp2.txt").delete(); } + @Test public void testFileWriterWithoutEncodingFromFileName() throws IOException { BufferedWriter writer=null; try { @@ -49,12 +60,14 @@ public class IOUtilsTestCase extends junit.framework.TestCase { new File("temp3.txt").delete(); } + @Test public void testFileCounting() throws IOException { IOUtils.writeFile("temp4.txt","hello\nworld",false); assertEquals(2,IOUtils.countLines("temp4.txt")); new File("temp4.txt").delete(); } + @Test public void testFileCopy() throws IOException { IOUtils.writeFile("temp5.txt","hello",false); IOUtils.copy(new File("temp5.txt"), new File("temp5copy.txt")); @@ -63,6 +76,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { new File("temp5copy.txt").delete(); } + @Test public void testFileCopyWithLineCap() throws IOException { IOUtils.writeFile("temp6.txt","hello\nyou\nworld",false); IOUtils.copy("temp6.txt","temp6copy.txt",2); @@ -71,6 +85,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { new File("temp6copy.txt").delete(); } + @Test public void testGetLines() throws IOException { IOUtils.writeFile("temp7.txt","hello\nworld",false); List lines=IOUtils.getLines("temp7.txt"); @@ -80,6 +95,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { new File("temp7.txt").delete(); } + @Test public void testFileWriterAppend() throws IOException { boolean append=true; IOUtils.writeFile("temp8.txt", "hello",!append); @@ -95,6 +111,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { new File("temp8.txt").delete(); } + @Test public void testCloseAllReaders() throws IOException { StringReader reader1=new StringReader("hello"); StringReader reader2=new StringReader("world"); @@ -115,6 +132,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { } } + @Test public void testDirCopying() throws IOException { IOUtils.writeFile("temp1/temp1.txt","hello",false); IOUtils.writeFile("temp1/temp2.txt","world",false); @@ -127,6 +145,7 @@ public class IOUtilsTestCase extends junit.framework.TestCase { assertTrue(!new File("temp2").exists()); } + @Test public void testDirCopyingWithFilter() throws IOException { IOUtils.writeFile("temp1/temp1.txt","hello",false); IOUtils.writeFile("temp1/temp2.txt","world",false); -- cgit v1.2.3