我在初始化一个简单的字符数组时遇到问题。 (值为 0)char 数组的大小更大和/或等于 2Mb。我已经搜索了互联网并阅读了我能找到的所有内容(从 What is the maximum size of buffers memcpy/memset etc. can handle? 到...我不知道)并尝试了许多不同的过程(从尝试将值附加到 char 数组到尝试...)。此代码的目的是使用 C 库 (NDK) 写入文件。如果我尝试写入等于或低于 1Mb 的值,下面显示的截图可以正常工作。请帮助我提供可以替代“memset”的建议。这是示例代码:
我的c库:
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <linux/errno.h>
#include <errno.h>
#include <fcntl.h>
#define APPNAME "AppLogger2"
#define ALOG(...) __android_log_print(ANDROID_LOG_INFO,APPNAME,__VA_ARGS__)
int fd_is_valid(int fd) {
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}
extern "C"
JNIEXPORT jboolean
JNICALL
Java_project_vasile_emanuel_gresanu_overwrite_1intrnal_1externals_1storage_utils_my_threads_WiperWorkerImpl_executeWiping(
JNIEnv *env, jclass clazz, jint fd, jlong bufferSize, jint patterntoWrite = 0) {
char str[80];
sprintf(str, "FileDescriptor Primit = %d", fd);
ALOG(str, __LINE__);
if (fd_is_valid(fd)) {
char buf[bufferSize];//allocate buffer
memset(buf, patterntoWrite, (size_t) bufferSize);// init buffer
while (true) {
if (0 < write(fd, buf, (size_t) bufferSize)) {// write to file
if (0 > fsync(fd)) //write to the raw disk
{
ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
break;
}
} else {
ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
break;
}
}
return JNI_TRUE;
} else {
ALOG("Sunt probleme cu file descriptorul primit!", __LINE__);
}
return JNI_FALSE;
}
三段Java代码:
class WiperWorkerImpl(val pathToFile: DocumentFile, ...): Runnable{
companion object {
const val useCExternalFunctionToOverWriteSpace = true
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
external fun executeWiping(fileDescriptorValue: Int, bytesToWrite:Long, patternToUse:Int): Boolean
override fun run() {
val pfd: ParcelFileDescriptor = contentResolver.openFileDescriptor(pathToFile.uri, "w")
if(checkTheRamSpaceForTheBytestThatAreGoingToBeWritten(bytesPerBlockToWriteLocalThread.get())) {
if (executeWiping(pfd.fd, bytesPerBlockToWriteLocalThread.get(), 0)) {
AppLogger.i("WiperWorkerImpl. Finish with success")
} else {
AppLogger.e("WiperWorkerImpl. Finished with error!")
}
}
closeFileDescriptor(pfd)
}
}
最佳答案
谢谢unwind , 你救了我。现在效果很好。这是正确的代码:
JNICALL
Java_project_vasile_emanuel_gresanu_overwrite_1intrnal_1externals_1storage_utils_my_threads_WiperWorkerImpl_executeWiping(
JNIEnv *env, jclass clazz, jint fd, jlong bufferSize, jint patterntoWrite = 0) {
char str[80];
sprintf(str, "FileDescriptor Primit = %d", fd);
ALOG(str, __LINE__);
if (fd_is_valid(fd)) {
char *buf = (char*) calloc(bufferSize, sizeof(char));//allocate buffer. Now it doesn't matter how big is the buffer
for(int i=0;i<bufferSize;i++)
{
buf[i] = 0;
}
while (true) {
if (0 < write(fd, buf, (size_t) bufferSize)) {// write to file
if (0 > fsync(fd)) //write to the raw disk
{
ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
break;
}
} else {
ALOG("Cred ca am ajuns la capatul de scriere.", __LINE__);
break;
}
}
return JNI_TRUE;
} else {
ALOG("Sunt probleme cu file descriptorul primit!", __LINE__);
}
return JNI_FALSE;
}
关于Android NDK 字符数组初始化超过 1Mb,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49401934/