Maybe I need to use this file later, but for now, I just want the md5 string.
Would you modify the DigestUtils class to close it automatically?
Code:
Result:
Comment From: sbrannen
For future reference, please do not provide screenshots of code and example output.
Rather, please provide text that can be copied-and-pasted.
Comment From: sbrannen
On my computer, the following test passes (i.e., with true, false) even if the FileInputStream is not closed.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import org.springframework.util.DigestUtils;
import static org.assertj.core.api.Assertions.*;
class DigestUtilsTests {
@Test
void test() throws Exception {
Path tmpDir = Files.createTempDirectory(getClass().getSimpleName());
File file = tmpDir.resolve("test.txt").toFile();
file.createNewFile();
String name = file.getAbsolutePath();
FileInputStream fis = new FileInputStream(name);
String md5Digest = DigestUtils.md5DigestAsHex(fis);
assertThat(fis.available()).isEqualTo(0);
System.out.println(md5Digest);
assertThat(new File(name).renameTo(tmpDir.resolve("demo.txt").toFile())).isTrue();
// fis.close();
assertThat(new File(name).renameTo(tmpDir.resolve("demo.txt").toFile())).isFalse();
}
}
Thus, unless I'm missing something, the use of DigestUtils.md5DigestAsHex(fis) does not have any adverse effect on your example.
Can you please confirm that the above test passes on your Windows computer as well?
As for whether DigestUtils.md5DigestAsHex(InputStream) should be modified to automatically close the supplied InputStream, that would be a breaking change for existing clients.
However, we can repurpose this issue to improve the Javadoc in that regard.
Comment From: wanjiaXG
For future reference, please do not provide screenshots of code and example output.
Rather, please provide text that can be copied-and-pasted.
all right, thank you for your reply.
Comment From: wanjiaXG
On my computer, the following test passes (i.e., with
true, false) even if theFileInputStreamis not closed.```java import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays;
import org.junit.jupiter.api.Test;
import org.springframework.util.DigestUtils;
import static org.assertj.core.api.Assertions.*;
class DigestUtilsTests {
@Test void test() throws Exception { Path tmpDir = Files.createTempDirectory(getClass().getSimpleName()); File file = tmpDir.resolve("test.txt").toFile(); file.createNewFile(); String name = file.getAbsolutePath(); FileInputStream fis = new FileInputStream(name);
String md5Digest = DigestUtils.md5DigestAsHex(fis); assertThat(fis.available()).isEqualTo(0); System.out.println(md5Digest); assertThat(new File(name).renameTo(tmpDir.resolve("demo.txt").toFile())).isTrue(); // fis.close(); assertThat(new File(name).renameTo(tmpDir.resolve("demo.txt").toFile())).isFalse();}
} ```
Thus, unless I'm missing something, the use of
DigestUtils.md5DigestAsHex(fis)does not have any adverse effect on your example.Can you please confirm that the above test passes on your Windows computer as well?
As for whether
DigestUtils.md5DigestAsHex(InputStream)should be modified to automatically close the suppliedInputStream, that would be a breaking change for existing clients.However, we can repurpose this issue to improve the Javadoc in that regard.
I dont know assertThat this method, i try convent the code to
import org.springframework.util.DigestUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class DigestUtilsTests {
public static void main(String[] args) throws IOException {
Path tmpDir = Files.createTempDirectory(DigestUtilsTests.class.getSimpleName());
File file = tmpDir.resolve("test.txt").toFile();
boolean newFile = file.createNewFile();
System.out.println(newFile);
String name = file.getAbsolutePath();
FileInputStream fis = new FileInputStream(name);
String md5Digest = DigestUtils.md5DigestAsHex(fis);
System.out.println(fis.available());
System.out.println(md5Digest);
boolean b1 = new File(name).renameTo(tmpDir.resolve("demo.txt").toFile());
boolean b2 = new File(name).renameTo(tmpDir.resolve("demo.txt").toFile());
System.out.println(b1);
System.out.println(b2);
}
}
result is
true
0
d41d8cd98f00b204e9800998ecf8427e
false
false
Comment From: rstoyanchev
I believe the underlying reason for this is that if a resource, such as an InputStream was opened externally, then it must also be up to the external caller to decide and control the closing. In other words the code that takes the InputStream cannot assume that closing it is the right thing to do.
This class for example is used in Spring MVC where the input stream is that of the HTTP response and it must not be closed.
Note also that this is a class mainly for internal use within the framework as the Javadoc says. You can of course use it but it is designed to serve framework needs, which sometimes means more flexibility in exchange for convenience.
Comment From: rstoyanchev
Oops, did not mean to close it. Yes I think the Javadoc can mention explicitly that InputStream must be closed externally.
Comment From: wanjiaXG
Oops, did not mean to close it. Yes I think the Javadoc can mention explicitly that
InputStreammust be closed externally.Oops, did not mean to close it. Yes I think the Javadoc can mention explicitly that
InputStreammust be closed externally.Oops, did not mean to close it. Yes I think the Javadoc can mention explicitly that
InputStreammust be closed externally.
Flexibility is more important, thank you for your answer. :D