java io追加到文件实现
java io append to file implementation
我在 Ubuntu 16.04
上使用 java-1.8.0-openjdk-amd64
我想了解在追加时文件发生了什么
假设我要附加到一个非常大的文件,Java 是否会将整个文件加载到内存中?我怎样才能看到本地调用?
来自java.io.FileOutputStream.java
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open0(String name, boolean append)
throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private void open(String name, boolean append)
throws FileNotFoundException {
open0(name, append);
}
更新:
正在看jdk8源码
src/solaris/native/sun/nio/ch/InheritedChannel.c:Java_sun_nio_ch_InheritedChannel_open0(JNIEnv
*env, jclass cla, jstring path, jint oflag)
JNIEXPORT jint JNICALL
Java_sun_nio_ch_InheritedChannel_open0(JNIEnv *env, jclass cla, jstring path, jint oflag)
{
const char* str;
int oflag_actual;
/* convert to OS specific value */
switch (oflag) {
case sun_nio_ch_InheritedChannel_O_RDWR :
oflag_actual = O_RDWR;
break;
case sun_nio_ch_InheritedChannel_O_RDONLY :
oflag_actual = O_RDONLY;
break;
case sun_nio_ch_InheritedChannel_O_WRONLY :
oflag_actual = O_WRONLY;
break;
default :
JNU_ThrowInternalError(env, "Unrecognized file mode");
return -1;
}
str = JNU_GetStringPlatformChars(env, path, NULL);
if (str == NULL) {
return (jint)-1;
} else {
int fd = open(str, oflag_actual);
if (fd < 0) {
JNU_ThrowIOExceptionWithLastError(env, str);
}
JNU_ReleaseStringPlatformChars(env, path, str);
return (jint)fd;
}
}
不,它不会将文件加载到内存中。这将无法附加到大文件。
实际逻辑取决于所使用的文件系统,但基本上只需要加载文件的最后一个块,用附加数据重写,并为任何进一步的附加数据写入额外的块。
你不用担心。如果您确实想担心它,请了解文件系统的工作原理。
我在 Ubuntu 16.04
上使用 java-1.8.0-openjdk-amd64我想了解在追加时文件发生了什么
假设我要附加到一个非常大的文件,Java 是否会将整个文件加载到内存中?我怎样才能看到本地调用?
来自java.io.FileOutputStream.java
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open0(String name, boolean append)
throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private void open(String name, boolean append)
throws FileNotFoundException {
open0(name, append);
}
更新:
正在看jdk8源码
src/solaris/native/sun/nio/ch/InheritedChannel.c:Java_sun_nio_ch_InheritedChannel_open0(JNIEnv *env, jclass cla, jstring path, jint oflag)
JNIEXPORT jint JNICALL
Java_sun_nio_ch_InheritedChannel_open0(JNIEnv *env, jclass cla, jstring path, jint oflag)
{
const char* str;
int oflag_actual;
/* convert to OS specific value */
switch (oflag) {
case sun_nio_ch_InheritedChannel_O_RDWR :
oflag_actual = O_RDWR;
break;
case sun_nio_ch_InheritedChannel_O_RDONLY :
oflag_actual = O_RDONLY;
break;
case sun_nio_ch_InheritedChannel_O_WRONLY :
oflag_actual = O_WRONLY;
break;
default :
JNU_ThrowInternalError(env, "Unrecognized file mode");
return -1;
}
str = JNU_GetStringPlatformChars(env, path, NULL);
if (str == NULL) {
return (jint)-1;
} else {
int fd = open(str, oflag_actual);
if (fd < 0) {
JNU_ThrowIOExceptionWithLastError(env, str);
}
JNU_ReleaseStringPlatformChars(env, path, str);
return (jint)fd;
}
}
不,它不会将文件加载到内存中。这将无法附加到大文件。
实际逻辑取决于所使用的文件系统,但基本上只需要加载文件的最后一个块,用附加数据重写,并为任何进一步的附加数据写入额外的块。
你不用担心。如果您确实想担心它,请了解文件系统的工作原理。