背景
常会遇到excel导出需求,那么导出的前提是文件需要创建,那么就来说一下文件创建的正确姿势
通常写法
public void createFile(){
String filePath = "C:\\a\\b\\c\\d.txt";
File file = new File(filePath);
if(!file.exists()){
file.createNewFile();
}
}
Q:思考一下这样写是否可行?
A:答案是否定的。进入createNewFile方法看一下
public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(path);
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.createFileExclusively(path); // --断点到这里--
}
/**
* Create a new empty file with the given pathname. Return
* <code>true</code> if the file was created and <code>false</code> if a
* file or directory with the given pathname already exists. Throw an
* IOException if an I/O error occurs.
*/
public abstract boolean createFileExclusively(String pathname)
throws IOException;
JNIEXPORT jboolean JNICALL
Java_java_io_WinNTFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
jstring path)
{
HANDLE h = NULL;
WCHAR *pathbuf = pathToNTPath(env, path, JNI_FALSE);
if (pathbuf == NULL)
return JNI_FALSE;
if (isReservedDeviceNameW(pathbuf)) {
free(pathbuf);
return JNI_FALSE;
}
h = CreateFileW(
pathbuf, /* Wide char path name */
GENERIC_READ | GENERIC_WRITE, /* Read and write permission */
FILE_SHARE_READ | FILE_SHARE_WRITE, /* File sharing flags */
NULL, /* Security attributes */
CREATE_NEW, /* creation disposition */
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OPEN_REPARSE_POINT, /* flags and attributes */
NULL);
if (h == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
if ((error != ERROR_FILE_EXISTS) && (error != ERROR_ALREADY_EXISTS)) {
// return false rather than throwing an exception when there is
// an existing file.
DWORD a = GetFileAttributesW(pathbuf);
if (a == INVALID_FILE_ATTRIBUTES) {
SetLastError(error);
JNU_ThrowIOExceptionWithLastError(env, "Could not open file");
}
}
free(pathbuf);
return JNI_FALSE;
}
free(pathbuf);
CloseHandle(h);
return JNI_TRUE;
}
INVALID_HANDLE_VALUE – Throw IOException
Exception in thread "main" java.io.IOException: 系统找不到指定的路径。
at java.base/java.io.WinNTFileSystem.createFileExclusively(Native Method)
正确姿势
public void createFile(){
String filePath = "C:\\a\\b\\c\\d.txt";
File file = new File(filePath);
File parentFile = file.getParentFile();
if(!parentFile .exists()){
file.mkdirs();
}
file.createNewFile();
}